我有一个为用户分配用户名的Web服务。内部,我正在调用一堆函数,以验证用户名是否存在于UserPrincipal,samAccountName,proxyaddresses和email字段中。
在单元测试中,此代码需要10秒钟才能运行。该代码在本地部署到Web服务器需要9分钟以上的时间才能运行。我认为这不是首次运行的问题,因为第二次所需的时间也一样长。我们的域有超过3万名用户,我必须搜索整个域以确保名称不存在。无法使用按需求缓存,因为我们需要进行最新检查。
我已经搜索了如何提高速度,但是还没有发现任何东西。
有人对如何提高性能有建议吗?
public bool DoesEmailExist(string email)
{
using (var context = GetPrincipalContext())
{
var userQuery = new UserPrincipal(context) { EmailAddress = email + "@*" };
var searcher = new PrincipalSearcher(userQuery);
var result = searcher.FindOne();
if (result == null)
{
var aliasQuery = new ExtendedUserPrincipal(context) { ProxyAddress = "*smtp:" + email + "@*" };
searcher = new PrincipalSearcher(aliasQuery);
var aliasResult = searcher.FindOne();
if (result == null)
{
return false;
}
}
return true;
}
}
private PrincipalContext GetPrincipalContext(string ou)
{
return new PrincipalContext(ContextType.Domain, dc, ou, ContextOptions.Negotiate);
}
编辑-我改用DirectorySearcher,速度似乎有所提高。现在,在运行的Web API上需要5分钟。我仍然想知道为什么我的单元测试要比Web API快得多。使用记录代码,在单元测试中对DoesUserNameExist的调用将花费7秒。通过运行的Web API,需要5分钟。
public bool DoesUserNameExist(string userName)
{
string filter = "(|(samAccountName={NAME})(UserPrincipalName={NAME}@*)(mail={NAME}@*)(proxyAddresses=*smtp:{NAME}@*))";
filter = filter.Replace("{NAME}", userName);
using (var de = new DirectoryEntry("LDAP://" + domainController + "/" + rootOU))
{
var searcher = new DirectorySearcher();
searcher.Filter = filter;
searcher.PageSize = 1;
var result = searcher.FindOne();
if (result != null)
{
return true;
}
return false;
}
}
最佳答案
尽管proxyAddresses属性已建立索引,但它仅对相等和以-开头的过滤器有所帮助,而对于以-结束的过滤器无效,并且包含一个。
快速:proxyAddresses=sth
,proxyAddresses=sth*
慢:proxyAddresses=*sth*
,proxyAddresses=*sth
我认为没有看起来像“ abcdsmtp:[email protected]”的proxyAddresses。
您可以简单地使用proxyAddresses=smtp:{NAME}@*