I’ve had some contact with a few Devs that are trying to build an AD-aware application and was semi-responsible for feeding they questions with great answers. Some of the questions involved simple attribute names or locations where data was stored within the directory, other questions were about performance. Then, just a few minutes ago, I found a question in the Newsgroups that pretty much ended up being an exact copy of the question that I’ve heard a couple of times the last days.
My LDAP search is taking pretty long – why is that? What can I do?
I wont’ go into all the details here but putÂ up a list of questions you may run through and ask yourself and check back that might be a cause of slow/expensive processing ofÂ LDAP queries against AD DS/AD LDS.Â
First of all, it’s important to define what “pretty long” means, really. Is it three seconds? Ten seconds? A minute?
Make sureÂ hardware is not the cause ofÂ the slow responses. Actually, hardware isÂ almost never the causeÂ here but you never know. Check how large your DIT is and how much RAM there is in yourÂ DCs. AD tries to fit (most of)theÂ DIT into RAMÂ so it can access it in-memory, saving I/O and valuable time during query processing. Is that machine under constant load? Try to target a different DC/LDS host to gather information from — does that work better?Attributes searched
Look at the attributes seached. What kind of attributes are part of your filter? Are there attributes that are indexed in AD? (hint: “adfind -sc indexed ldapDisplayName -nodn” for a list of indexed attributes). If there’s no indexed attributes in your query, AD’s going to crawl the whole DIT to search for results (every time!). Help AD be more efficient by either including an indexed attribute in your search filter or indexing an attribute that’s part of your search that currently isn’t indexed. Including an already indexed attribute to your search is probably your best bet here. If you’re searching for users or contacts, try to include that in your search filter ( &(objectClass=user)(objectCategory=person) ). Don’t search for attributes that have little entropy. If 80% of the objects in your directory have a value in attribute x, it’s not worth filtering (x=*). If you’re attribute only has a couple of possible state (preferredHand=left) where only “left” and “right” are possible values, including that attribute to the filter might not shrink the search base noticably.
Try to limit the result base as much as you can by defining the mostÂ limiting filter possible.Question the search base
Where are you searching? Are you using the domain root as a search base when all the results are in an OU somewhere in the tree? Try to be specific from there and how far you want to search. Don’t use “Subtree” searches when you know the search results are direct child objects of a specific OU. If you know where you can expect search results, target the search specifically there. Try to create multiple searches with different search roots — that may be more efficient than searching once and targeting the domain root.What is actually taking *so* long?
Turn on diagnostics on the server to check whether you’re running inefficient or expensive queries. A good starting point is “Field Engineering” (http://www.frickelsoft.net/blog/?p=243) and Performance Counters.
Un-Complex your search
Try to tearch the search apart. Are you using a lot of NOT (!) operators in your search? You have some wildcard filters (x=*heim) (y=*text*)Â (z=400*)Â in there, too? Try to remove some of the filters one by one and see whether your search performs faster (while keeping an eye on the search results count, of course!)Compare with other apps
Compare the search with other apps. You have that application in front of you and you know the query it fires to AD? Great, compare the query performance with LDP or ADfind and use their STATS commands/controls to compare the performance. If LDP and ADfind perform well on the same filters, chances are your app just does inefficient things with the search results. Compare the searches right after you rebooted a server with searches after it’s been running for some time. Is there a performance increase? How do ADFind and LDP perform then?
Try to fire up a network trace app (wireshark, network monitor) to see what’s going on on the wire. Is that app targeting a specific LDAP server or is it burning time to find a server using incorrect DNS information? Does it repeat some LDAP queries over and over again? Is the program working correctly i.e. searching the directory by telling it only to return necessary/wanted attributes from the result set or is the whole object torn over the line (I know .NET isÂ a sucker in this!)?