Platform SDK: Active Directory, ADSI, and Directory Services
Creating Efficient Queries
There are several concepts you should consider when executing a query. The following list identifies the most important ones.
Make sure the query filter contains at least one indexed attribute. See Indexed Attributes.
Search on objectCategory instead of objectClass, because objectClass is not an indexed property. The statement (objectClass=foo) refers to directory objects in which foo represents any class in the object's class hierarchy, whereas (objectCategory=foo), refers to those directory objects in which foo identifies a specific class in the object's class hierarchy. The objectClass property can take multiple values, whereas objectCategory takes a single value and is, thus, better suited for type matching of objects in a directory search. ADSI uses this as the default matching criterion. Searches using one objectClass are not scalable to large databases. ADSI supports (objectCategory=SomeDN) and (objectCategory=Ldap_Display_Name_of_Class), for example, (objectCategory=user). The exception to this is that the LDAP search filter (objectClass=*) does not specify a search on object class, but merely tests for the presence of the objects. See Object Class and Object Category.
Avoid searching for text in the middle and on the end of a string. For example, "cn=*hille*" or "cn=*larouse". Using more specific matching criteria tends to boost search performance. This is because Active Directory™ evaluates all predicates, identifies the indices, and then picks one index that it considers most likely to yield the smallest set of returned values.
Chasing referrals is expensive. Try to take advantage of the global catalog if you are considering subtree searches. See Referral Chasing.
Assume a subtree search will return a large result set. Use paging when performing subtree searches. The server will then be able to stream a large result set in chunks reducing the server side memory resources. This effectively flattens out network usage and reduces the need for sending extremely large chunks of data over a network. See Paging.
Restrict queries to retrieve only what is necessary.
One search of an object that reads two attributes is cheaper than two searches of the same object, each returning one attribute.
Bind to an object once and hang onto the binding handle for the rest of your session. Do not bind and unbind for each call. If you are using ADO or OLE DB, do not create many connection objects.
Read the rootDSE once and remember its contents for the rest of your session. See Serverless Binding and RootDSE in the Binding chapter.
Persist references to objects as GUIDs, not distinguished names, in order to be rename and delete safe. For more information, see Using objectGUID to Bind to an Object.