Member 1097736 Ответов: 0

Некластеризованное индексирование не отражается на производительности запроса


У меня есть таблица, которая регистрирует логины пользователей и приложение, из которого пользователь вошел в систему.

| Нет | Идентификатор Пользователя | Приложения | Датавремя |
-------------------------------------------

Эта таблица содержит более 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. Если есть какие-либо очевидные недостающие индексы, план выполнения покажет их вам.

0 Ответов