I’m afraid I can’t dedicate a long post on this tonight, but should be able to revisit tomorrow.
edit: I guess I did have time for a long post
The main issue we usually see with query efficiency is the “looping” effect that comes from creating a cross-product. When you take an operation like
(relevant fixlets of it) of bes computers whose (some condition)
What actually happens, is that for each computer, the query for ‘relevant fixlets’ is repeated, along with whatever filters you are applying for that fixlet selection.
If you have ten computers, the ‘relevant fixlets’ query is repeated ten times. A thousand computers? A thousand times through the ‘relevant fixlets’ loop.
The most authoritative guide on this behavior, and how to optimize, is in @brolly33’s post at Efficient Session Relevance Query for Computer Properties
The primary tactic there is for computer property lookups, but can be applied to Fixlet/Computer couplings as well. The approach is to first build a filter for computers, and combine those computers into a ‘set’. Since a ‘computer set’ is actually a single object, that prevents repeating the ‘property’ or ‘fixlet’ lookup and filtering. Perform the Fixlet filtering (creating a ‘bes fixlet set’), and then after performing all the fixlet and computer lookups, unwind the two sets and match the results against each other.
The base form could start with something like
(
set of bes fixlets whose (exists applicable computers of it and category of it contains (case insensitive regex "Security\sAdvisory|Security\sHotfix| Security\sUpdate|Service\sPack"
, set of bes computers whose (id of it is contained by set of (123;456;789)
)
By creating the ‘sets’, the computer lookups are performed only once (not repeated for every fixlet), and the fixlet lookups are also performed only once (not repeated for every computer)
From there, you can unwind the sets and only keep the results where a fixlet member is relevant on the computer member…
(elements of item 0 of it, elements of item 1 of it)
whose (relevant flag of result (item 0 of it, item 1 of it) of
(
set of bes fixlets whose (exists applicable computers of it and category of it contains (case insensitive regex "Security\sAdvisory|Security\sHotfix| Security\sUpdate|Service\sPack"
, set of bes computers whose (id of it is contained by set of (123;456;789)
)
I’m not connected to my lab right now but I think that should give you a result where ‘item 0’ is the relevant fixlet and ‘item 1’ is the applicable computer for that fixlet. From there you can lookup Fixlet properties from item 0 and Computer properties from item 1. Something like
(
name of item 0 of it /* Fixlet Name */
, cve id list of item 0 of it /* Fixlet CVE ID List */
, name of site of item 0 of it /* Fixlet Site */
, source severity of item 0 of it /* Fixlet Severity */
, source release date of item 0 of it /* Fixlet Release Date */
, id of item 1 of it /* Computer ID */
, name of item 1 of it | "Computername Not Reported" /* ComputerName or message */
, last report time of item 1 of it /* Computer Last Reported */
) of
(elements of item 0 of it, elements of item 1 of it)
whose (relevant flag of result (item 0 of it, item 1 of it) of
(
set of bes fixlets whose (
exists applicable computers of it
and exists cve id list of it
and category of it contains
(case insensitive regex "Security\sAdvisory|Security\sHotfix| Security\sUpdate|Service\sPack")
)
, set of bes computers whose (id of it is contained by set of (123;456;789)
)
Let me know if this helps. If there’s a bug in here I should be able to check it out in my lab tomorrow. For performance, the more filtering you can do on the computers or fixlets up-front, the better - especially if you can limit the sites for the fixlets of interest so that we don’t scan every fixlet site.