2

我在创建的一个小Active Directory搜索工具中遇到了一些性能问题。

这个问题与这个问题非常相似,基本上我正在通过以下代码从 AD 检索用户列表:

DirectoryEntry dEntry = new DirectoryEntry("LDAP://ldappath");
DirectorySearcher searchdirectory = new DirectorySearcher(directory);

searchdirectory.Filter = "(&(objectClass=user)(objectcategory=person)(|(name=" + searchString + "*)(givenname=" + searchString + "*)(sn=" + searchString + "*)(mail=" + searchString + "*)(telephonenumber=" + searchString + "*)(samaccountname=" + searchString + "*)))";
searchdirectory.Sort.PropertyName = "name"; // Optional sorting by attribute
searchdirectory.SizeLimit = 100; // Sets the search limit
searchdirectory.PageSize = 1000; // Sets the results per returned page

SearchResultCollection collectionResults = searchdirectory.FindAll();

directory.Dispose();
searchdirectory.Dispose();

List<SearchResult> results = new List<SearchResult>();

for (int i = 0; collectionResults.Count > i; i++)
{
    results.Add(collectionResults[i]);
}

return results;

无论结果量(服务器是具有大量资源的 2012-R2 虚拟机)或返回的属性如何,上面都会立即返回SearchResultCollection近乎即时(~4ms),当任何尝试访问时会出现问题SearchResultCollection,包括SearchResultCollection.Count.

对于所有属性的 10 个结果并且searchString为空白,大约需要 65ms,100 个结果需要 240ms,1000 个需要 1950ms。无论结果数或搜索字符串如何,搜索实际字符串似乎都会为任何数量的结果增加约 350 毫秒。与“*a”相比,搜索“a”似乎也更慢。

这通常会很好,但在速度较慢的 PC 上,这可能需要 30 多秒才能获得 50 个结果。

速度受 中的内容影响SearchResultCollection,例如,如果我添加searchdirectory.PropertiesToLoad.Add("cn")它将花费一小部分时间(1/10 或更低)。所以我假设问题源于其中的数据量SearchResultCollection以及将其缓存/移动到内存或类似的时间(编程仍然有点新)。如果我更改它正在搜索的字段,它也会产生很大的不同,但这不应该产生影响,因为时间问题是访问时而SearchResultCollection不是调用时FindAll()

 

我想知道和澄清的是为什么在访问时需要时间SearchResultCollection而不是在实际执行搜索时,据我所知,当我调用时它应该从 LDAP 检索所有结果FindAll()

如果有人可以以任何方式(通过示例或指向学习资源)帮助使此代码更有效地运行,而不会严重影响返回的属性或搜索参数,那也是很棒的。

我知道 Powershell 可以立即检索这些类型的详细信息,所以我认为必须有更好的方法来解决这个问题。

4

1 回答 1

0

在 .NET 中很常见的是,在您实际访问列表之前,各种类型的列表都不完全可用。所以那部分并不奇怪。

此外,如果您不设置PropertiesToLoad,则为结果中的每个帐户返回所有具有值的属性。所以最好PropertiesToLoad只设置你需要的属性。

是的,查询会影响性能。这取决于您要搜索的属性。在这种情况下,telephoneNumber不被索引。这意味着它必须查看每个帐户以检查电话号码。我怀疑如果您只是删除该条件,那么您的查询会快得多。

这可能会或可能不会帮助您,但您可以查看Ambiguous Name Resolution。您在 LDAP 查询中使用它(anr=" + searchString + ")",AD 将搜索各种属性(在文档中列出)。

正如 EricLavault 所提到的,您应该处理结果。从文档中FindAll()

由于实现限制,SearchResultCollection 类在垃圾回收时无法释放其所有非托管资源。为防止内存泄漏,您必须在不再需要 SearchResultCollection 对象时调用 Dispose 方法。

于 2018-05-02T19:27:03.107 回答