Некластеризованное индексирование не отражается на производительности запроса
У меня есть таблица, которая регистрирует логины пользователей и приложение, из которого пользователь вошел в систему.
| Нет | Идентификатор Пользователя | Приложения | Датавремя |
-------------------------------------------
Эта таблица содержит более 1 миллиона записей.
Я запрашиваю список записей с помощью LINQ на основе списка userid и приложения ниже.
List<string> relyingParties = new List<string>(){"AAA","BBB","CCC","DDD"}; //Filtering the users by UserID and Application var userLogActionList = dbContext.LogUserAction.Where(x => userIDList.Contains((x.UserID.Value)) && relyingParties.Contains(x.ApplicationLoggedIn)).ToList());
Среднее время, необходимое для извлечения из БД, занимает более 15 секунд для ввода 100 идентификаторов пользователей в userIDList, что очень плохо, я чувствую.
Я хочу иметь лучшую производительность для запроса и извлечения данных. Я наткнулся на индексацию во время поиска в интернете.
Я очень новичок в концепции индексации. Поскольку у меня уже есть PK в таблице, у него есть кластеризованный индекс, поэтому я не смог создать еще один кластеризованный индекс в таблице.
Я реализовал некластеризованный индекс для столбца UserID.
IX_LogUserAction_UserID
Если я выполняю SQL-запрос в SQL server,
SELECT * FROM [XYZDB].[dbo].[LogUserAction] WITH (INDEX([IX_LogUserAction_UserID])) where UserID='0cef394e-06ac-49cf-8c62-2a37299913e1'
Я вижу план пути выполнения для поиска и сканирования таблицы(когда индексации нет).
Насколько мне известно, если индексирование применяется к столбцу, это увеличит производительность запроса.
Но если я запускаю тот же код Linq выше, где я пытаюсь извлечь записи, производительность остается прежней(около 15 секунд).
Может ли кто-нибудь помочь мне в деталях, что я делаю не так или где я иду не так?
Ваш ответ очень ценится.
Что я уже пробовал:
List<string> relyingParties = new List<string>(){"AAA","BBB","CCC","DDD"}; //Filtering the users by UserID and Application var userLogActionList = dbContext.LogUserAction.Where(x => userIDList.Contains((x.UserID.Value)) && relyingParties.Contains(x.ApplicationLoggedIn)).ToList());
SELECT * FROM [XYZDB].[dbo].[LogUserAction] WITH (INDEX([IX_LogUserAction_UserID])) where UserID='0cef394e-06ac-49cf-8c62-2a37299913e1'
F-ES Sitecore
Возможно, вам захочется преобразовать это в хранимую процедуру, чтобы вы могли делать такие вещи, как операторы CTE и т. д. Вы можете получить желаемую производительность, если создадите табличную переменную, содержащую искомые идентификаторы, и выполните соединение этой таблицы с таблицей LogUserAction. Если вы используете LINQ, вы оставляете его на усмотрение LINQ, чтобы решить SQL, и он, вероятно, использует "IN" для выполнения поиска, и это всегда будет иметь низкую производительность.
Member 1097736
Спасибо за ответ. Могу ли я узнать, есть ли другой способ повысить производительность запросов и сократить время ?
Richard Deeming
Проблема в том, что ваш тестовый запрос не отражает фактический запрос, который вы выполняете из LINQ.
Тестовый запрос ищет записи для одного UserID
, так что индекс хорошо подходит.
Запрос LINQ ищет записи с одним из списка UserID
значения, и один из списка ApplicationLoggedIn
ценности. Вполне возможно, что оптимизатор запросов решил, что ваш индекс не подходит для этого запроса.
Вам необходимо изучить необработанный SQL-запрос, сгенерированный вашим запросом LINQ, и изучить план выполнения этого запроса в среде SQL Server Management Studio. Если есть какие-либо очевидные недостающие индексы, план выполнения покажет их вам.