来自 LDAP 请求的 SearchResultCollection 的性能问题
Performance issue with a SearchResultCollection from an LDAP request
我在自己创建的 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;
以上returns SearchResultCollection
无论结果量(服务器是2012-R2 VM,具有大量资源)或返回的属性如何,都会立即(~4ms),问题当任何尝试访问 SearchResultCollection
时发生,包括 SearchResultCollection.Count
.
所有属性的10个结果和searchString
为空,大约需要65ms,100个结果需要240ms,1000个需要1950ms。搜索实际字符串似乎会向任意数量的结果添加 ~350 毫秒,无论结果数或搜索字符串如何。与“*a”相比,搜索 "a" 似乎也更慢。
这通常很好,但在速度较慢的 PC 上,即使是 50 个结果也可能需要 30 多秒。
速度受 SearchResultCollection
中内容的影响,例如,如果我添加 searchdirectory.PropertiesToLoad.Add("cn")
,则只需要一小部分时间(1/10 或更少)。因此,我假设问题源于 SearchResultCollection
中的数据量以及 cache/move 将其存储到内存或类似设备所需的时间(对于编程来说仍然有点新)。
如果我更改它搜索的字段也会有很大的不同,但这应该不会有什么不同,因为时间问题是在访问 SearchResultCollection
时而不是在调用 FindAll()
.[=24 时=]
我想知道并澄清的是,为什么在访问 SearchResultCollection
而不是在实际执行搜索时需要时间,据我所知,当我调用时它应该从 LDAP 检索所有结果FindAll()
.
如果有人可以以任何方式(通过示例或指向学习资源)帮助使此代码 运行 更有效,而不会严重影响返回的属性或搜索参数,那就太好了.
我知道 Powershell 可以立即检索这些类型的详细信息,所以我认为一定有更好的方法来解决这个问题。
在您实际访问列表之前,各种类型的列表不完全可用在 .NET 中是很常见的。所以这部分并不奇怪。
此外,如果您未设置 PropertiesToLoad
,则结果中的每个帐户都会返回 所有 具有值的属性。因此,最好只将 PropertiesToLoad
设置为您需要的属性。
是的,查询会影响性能。这取决于您要搜索的属性。在这种情况下,telephoneNumber
没有被索引。这意味着它必须查看 每个帐户 以检查 phone 号码。我怀疑如果你只是删除那个条件,那么你的查询会快得多。
这可能对你有帮助,也可能没有帮助,但你可以看看 Ambiguous Name Resolution。您在 LDAP 查询中使用它 (anr=" + searchString + ")"
,AD 将搜索各种属性(在文档中列出)。
正如 EricLavault 提到的,您应该处理结果。来自 the documentation for FindAll()
:
Due to implementation restrictions, the SearchResultCollection class
cannot release all of its unmanaged resources when it is garbage
collected. To prevent a memory leak, you must call the Dispose method
when the SearchResultCollection object is no longer needed.
我在自己创建的 Active Directory
搜索工具中遇到了一些性能问题。
这个问题与
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;
以上returns SearchResultCollection
无论结果量(服务器是2012-R2 VM,具有大量资源)或返回的属性如何,都会立即(~4ms),问题当任何尝试访问 SearchResultCollection
时发生,包括 SearchResultCollection.Count
.
所有属性的10个结果和searchString
为空,大约需要65ms,100个结果需要240ms,1000个需要1950ms。搜索实际字符串似乎会向任意数量的结果添加 ~350 毫秒,无论结果数或搜索字符串如何。与“*a”相比,搜索 "a" 似乎也更慢。
这通常很好,但在速度较慢的 PC 上,即使是 50 个结果也可能需要 30 多秒。
速度受 SearchResultCollection
中内容的影响,例如,如果我添加 searchdirectory.PropertiesToLoad.Add("cn")
,则只需要一小部分时间(1/10 或更少)。因此,我假设问题源于 SearchResultCollection
中的数据量以及 cache/move 将其存储到内存或类似设备所需的时间(对于编程来说仍然有点新)。
如果我更改它搜索的字段也会有很大的不同,但这应该不会有什么不同,因为时间问题是在访问 SearchResultCollection
时而不是在调用 FindAll()
.[=24 时=]
我想知道并澄清的是,为什么在访问 SearchResultCollection
而不是在实际执行搜索时需要时间,据我所知,当我调用时它应该从 LDAP 检索所有结果FindAll()
.
如果有人可以以任何方式(通过示例或指向学习资源)帮助使此代码 运行 更有效,而不会严重影响返回的属性或搜索参数,那就太好了.
我知道 Powershell 可以立即检索这些类型的详细信息,所以我认为一定有更好的方法来解决这个问题。
在您实际访问列表之前,各种类型的列表不完全可用在 .NET 中是很常见的。所以这部分并不奇怪。
此外,如果您未设置 PropertiesToLoad
,则结果中的每个帐户都会返回 所有 具有值的属性。因此,最好只将 PropertiesToLoad
设置为您需要的属性。
是的,查询会影响性能。这取决于您要搜索的属性。在这种情况下,telephoneNumber
没有被索引。这意味着它必须查看 每个帐户 以检查 phone 号码。我怀疑如果你只是删除那个条件,那么你的查询会快得多。
这可能对你有帮助,也可能没有帮助,但你可以看看 Ambiguous Name Resolution。您在 LDAP 查询中使用它 (anr=" + searchString + ")"
,AD 将搜索各种属性(在文档中列出)。
正如 EricLavault 提到的,您应该处理结果。来自 the documentation for FindAll()
:
Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. To prevent a memory leak, you must call the Dispose method when the SearchResultCollection object is no longer needed.