Разница между запросом SQL и использованием индекса по столбцу Datetime - PullRequest
0 голосов
/ 05 июля 2019

У меня есть простая таблица с индексом в столбце DateTime.

Может кто-нибудь объяснить мне, какой из этих двух запросов будет использовать индекс?

CREATE TABLE exams
(
    name VARCHAR(50),
    grade INT,
    date DATETIME
);

CREATE INDEX date_idx ON exams(date);

SELECT * 
FROM exams 
WHERE date = '2018-01-01';      -- doesn't use index?

SELECT * 
FROM exams 
WHERE MONTH(date) = 1;      -- uses index?

Ответы [ 2 ]

6 голосов
/ 05 июля 2019

Существуют разные способы решения этой проблемы с помощью SQL Engine. Давайте вставим некоторые примерные данные в вашу таблицу:

DROP TABLE if exists exams;

CREATE TABLE exams(
  name varchar(50),
  grade INT,
  date datetime
);

INSERT exams
SELECT TOP (5000)  CONCAT('name', row_number() over(order by t1.number))
                   ,6
                   ,'2019-07-01'
FROM master..spt_values t1 
CROSS JOIN master..spt_values t2

INSERT exams
SELECT TOP (5)  CONCAT('name', row_number() over(order by t1.number))
                   ,6
                   ,'2019-07-02'
FROM master..spt_values t1 
CROSS JOIN master..spt_values t2

CREATE INDEX date_idx ON exams(date);

Как видите, мы вставили:

  • 5 000 строк для даты 2019-07-01
  • 5 строк для даты 2019-07-02

Теперь выполним следующие запросы:

SELECT * FROM exams WHERE date= '2019-07-01'; 

SELECT * FROM exams WHERE date= '2019-07-02'; 

SELECT * FROM exams WHERE MONTH(date)=1;

и проверьте планы выполнения:

enter image description here

В первом запросе движок знает (из-за статистики), что почти все данные будут прочитаны, поэтому он выполняет table scan в вашей куче.

Во втором запросе механизм видит, что будет возвращено только несколько записей, поэтому нет необходимости читать все данные - он использует индекс и выполняет index seek.

В последнем случае индекс нельзя использовать, поскольку запрос не sargable .

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

4 голосов
/ 05 июля 2019

Ну, я считаю, что истина совершенно противоположна:

Первый запрос использует индекс, а второй НЕ НЕТ.

Почему второй запрос не использует индекс?Поскольку индексированный столбец заключен в функцию, которая не позволяет SQL Server использовать индекс.

Индекс можно рассматривать как способ хранения записей.Применение функции к индексированному столбцу может изменить порядок хранимых записей, поэтому при использовании функции индекс может быть недействительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...