2014-10-22 4 views
2

У меня есть веб-служба, которая присваивает имена пользователей людям. внутри Я вызываю кучу функций, которые проверяют, существует ли имя пользователя в AD по полям UserPrincipal, samAccountName, прокси-адрес и адрес электронной почты.Почему код Principalsearcher значительно медленнее

В модульном тестировании этот код занимает 10 секунд. Развернутый на веб-сервер локально код занимает 9 минут для запуска. Я не думаю, что это первая проблема с запуском, потому что она занимает столько же времени, сколько и во второй раз. В нашем домене более 30 тыс. Пользователей, и я должен искать весь домен, чтобы убедиться, что имя не существует. Для кэширования требований не может быть использовано, потому что нам нужна проверка до минуты.

Я искал, как улучшить скорость, но ничего не обнаружил.

У кого-нибудь есть предложения по улучшению производительности?

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, и скорость, похоже, улучшила некоторые из них. Теперь он занимает 5 минут на запущенной веб-ави. Я все еще хотел бы знать, почему мой модульный тест значительно быстрее, чем веб-ави. Используя код ведения журнала, вызов для функцииUsUserNameExist в модульном тесте занимает 7 секунд. Через запущенную веб-ави это занимает 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; 
     } 
    } 

ответ

2

Хотя ProxyAddresses атрибут индексируется, это помогает только при равных и запуск с фильтром, но не конечным с и содержит те.

  • Быстро: proxyAddresses=sth, proxyAddresses=sth*
  • Slow: proxyAddresses=*sth*, proxyAddresses=*sth

Я не думаю, что есть ProxyAddresses, что выглядит как "abcdsmtp: [email protected]".
Вы можете просто использовать proxyAddresses=smtp:{NAME}@*