Существуют разные способы решения этой проблемы с помощью 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;
и проверьте планы выполнения:
В первом запросе движок знает (из-за статистики), что почти все данные будут прочитаны, поэтому он выполняет table scan
в вашей куче.
Во втором запросе механизм видит, что будет возвращено только несколько записей, поэтому нет необходимости читать все данные - он использует индекс и выполняет index seek
.
В последнем случае индекс нельзя использовать, поскольку запрос не sargable .
Итак, механизм решает, использовать индекс или нет, и выполнять поиск или сканирование. Единственное, что вы можете сделать, это убедиться, что ваши индексы покрыты, ваша статистика обновлена, а ваши запросы могут быть саргматичными.