0

У меня средняя база пользователей в Memberships и Users таблицах (более 10 000 пользователей). По мере роста числа применений процесс входа в систему постепенно замедляется до неприемлемого. Теперь для проверки подлинности одного пользователя требуется 2 секунды, что для меня катастрофа. Поэтому я начал исследовать, что происходит.Вход для провайдера членства не использует индексы из-за нижнего()

Оказалось, что на столбе Username нет указателя в таблице Users. Поэтому я создал его. Для моего большого удивления это не помогло. Затем я понюхал процесс входа в систему с помощью SQL Profiler и обнаружил, что запрос аутентификации (sp_executesql, это LinQ, а не хранимая процедура!) Содержит функцию lower() в столбце Username, что делает невозможным использование SQL-индексом SQL Server! Вкусно!

Мои вопросы:

  1. почему?
  2. как решить это, не переписывая метод провайдера (желательно)?
+0

Вы разделяли этот сценарий с MS с помощью форума? – SBirthare

+0

Не совсем. Думаю, этот форум намного лучше. –

ответ

0

Вот ответы ваших двух вопросов:

Ответ 1: Если функции используются в ИНЕКЕ этой силы SQL Server, чтобы сделать сканирование таблицы сканирования или индекс, чтобы получить правильные результаты вместо делать поиск индекса, если есть индекс, который можно использовать. Причина этого заключается в том, что значение функции должно оцениваться для каждой строки данных, чтобы определить ее соответствие вашим критериям. Подробнее об этом см. В разделах here и here.

Апзег 2: При хранении имя пользователя, хранить его либо в нижнем регистре или верхнем регистре, и вместо того, чтобы применять функцию на колонке, применять его на значение:

например,

Users.Where(x=>x.UserName == username.ToLower()); 

или

User.Where(x=>x.UserName == username.ToUpper()); 
+0

Спасибо Nitin, но это не ответ для меня, это ответ для Microsoft, который создал этот супер-неэффективный запрос. Они не изменят его для меня точно. И я не собираюсь переписывать весь членский провайдер. Любые другие советы? –