Добавление предложения WHERE к запросу замедляет запрос - даже если столбец проиндексирован - PullRequest
1 голос
/ 24 июня 2019

Таким образом, таблица пользователей имеет 40 миллионов строк. Приведенный ниже запрос выполняется достаточно быстро (менее 1 секунды), если у меня нет предложения WHERE Если я добавлю в запрос предложение WHERE, для возврата набора результатов потребуется около 10 минут. Я добавил индекс для столбца UserType, но он по какой-то причине не влиял на время отклика

  CREATE INDEX idx_users_user_type ON Users (UserType);

Запрос:

SELECT  TOP 100
        *
FROM Users u
    INNER JOIN Company c ON c.ID = u.CompanyID
    INNER JOIN Location l ON l.ID = u.LocationId
WHERE
    u.UserType = 'manager'

Для UserType есть только 3 значения:

manager
employee
temp

Я не хочу менять столбец на значение INT, если это возможно, потому что процесс ETL импортирует данные в эту таблицу, которые сейчас трудно изменить.

Ответы [ 2 ]

5 голосов
/ 24 июня 2019

Во-первых, вы должны прочитать эту статью об использовании TOP без ORDER BY.Короткая версия: вы не можете гарантировать, что результаты будут одинаковыми при каждом запуске, если у вас нет ORDER BY.

Первый запрос выполняется быстро, потому что SQL Server просто выполняет TABLE SCAN для * 1008.* первые 100 строк.Легко.Теперь вы добавляете предложение WHERE ... SQL Server должен найти все строки, в которых этот предикат имеет значение true.Конечно, у вас есть индекс, это может помочь.SQL Server будет (или может) использовать этот индекс, но если он это сделает, ему придется выполнить поиск ключей, чтобы получить остальные столбцы (поскольку вы SELECT *).Таким образом, он должен сделать намного больше работы.Весьма вероятно, что индекс даже не используется, поскольку SQL Server может решить, что быстрее просто выполнить TABLE SCAN, чтобы проверить этот предикат в каждой строке, вместо поиска ключа.Это, конечно, означает, что вам нужно прочитать 40 миллионов строк (проверьте, насколько велика ваша таблица ... это должно войти в память. Бьюсь об заклад, она выгружается на диск, может быть, даже разлив в TEMPDB ).

Итак, конечно, это будет медленнее ... вы проверяете условие по 40 миллионам строк вместо того, чтобы вытягивать random TOP 100.Если вам нужна дополнительная помощь, нам нужны планы выполнения как минимум со всеми операторами DDL (создать таблицу, создать индекс).

Другие варианты для исследования:

1 голос
/ 24 июня 2019

Вы можете добавить индекс:

CREATE INDEX idx_users_user_type_company_id_location_id 
          ON Users (CompanyId, LocationId,UserType);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...