Как уже упоминалось, индексирование является мощным инструментом для ускорения запросов. Порядок индекса, однако, принципиально важен.
Индекс в порядке (ExamEntry) затем (Student_ID) затем (Grade) будет почти бесполезен для поиска экзаменов, где студент сдал.
Индекс в обратном порядке подошел бы идеально, если бы все, что вам нужно, - это найти, какие экзамены были сданы. Это позволило бы обработчику запросов быстро идентифицировать строки для сданных экзаменов и просто обрабатывать их.
В MS SQL Server это можно сделать с помощью ...
CREATE INDEX [IX_results] ON [dbo].[results]
(
[Grade],
[Student_ID],
[ExamEntry]
)
ON [PRIMARY]
(я рекомендую прочитать больше об индексах, чтобы увидеть, какие есть другие опции, такие как ClusterdIndexes и т. Д., И т. Д.)
С этим индексом следующий запрос сможет очень быстро игнорировать «провальные» экзамены и просто отображать студентов, которые когда-либо сдавали экзамен ...
(Предполагается, что если вам когда-нибудь исполнится более 60 лет, вы будете считаться пропуском, даже если впоследствии вы снова сдадите экзамен и получите 27).
SELECT
Student_ID
FROM
[results]
WHERE
Grade >= 60
GROUP BY
Student_ID
Если вам определенно нужно самое последнее значение, вам нужно изменить порядок индекса обратно на что-то вроде ...
CREATE INDEX [IX_results] ON [dbo].[results]
(
[Student_ID],
[ExamEntry],
[Grade]
)
ON [PRIMARY]
Это потому, что первое, что нас интересует, - это самый последний экзамен для каждого учащегося. Что может быть достигнуто с помощью следующего запроса ...
SELECT
*
FROM
[results]
WHERE
[results].ExamEntry = (
SELECT
MAX([student_results].ExamEntry)
FROM
[results] AS [student_results]
WHERE
[student_results].Student_ID = [results].student_id
)
AND [results].Grade > 60
Подобный подзапрос может показаться медленным, тем более что он выполняется для каждой строки в [results].
Это, однако, не тот случай ...
- Основной и дополнительный запросы ссылаются на одну и ту же таблицу
- Механизм запросов просматривает индекс для каждого уникального Student_ID
- Подзапрос выполнен, для этого Student_ID
- Механизм запросов уже находится в этой части индекса
- Таким образом, новый поиск по индексу не требуется
EDIT:
Был сделан комментарий, что при 1000 записях индексы не актуальны. Следует отметить, что в вопросе указано, что возвращено 1000 записей, а не то, что таблица содержит 1000 записей. Если бы базовый запрос занимал столько времени, сколько указано, я бы поспорил, что в таблице много более 1000 записей. Может быть, это можно уточнить?
EDIT:
Я только что исследовал 3 запроса с 999 записями в каждом (3 результата экзамена для каждого из 333 студентов)
Метод 1: ГДЕ a.ExamEntry = (ВЫБЕРИТЕ МАКС. (B.ExamEntry) ИЗ РЕЗУЛЬТАТОВ [a] ГДЕ a.Student_ID = b.student_id)
Метод 2: ГДЕ a.ExamEntry IN (ВЫБЕРИТЕ МАКС. (ExamEntry) ИЗ РЕЗУЛЬТАТОВ GROUP BY Student_ID)
Метод 3: ИСПОЛЬЗОВАНИЕ ВНУТРЕННЕГО СОЕДИНЕНИЯ вместо предложения IN
Были найдены следующие моменты:
Method QueryCost(No Index) QueryCost(WithIndex)
1 23% 9%
2 38% 46%
3 38% 46%
Итак, Query 1 быстрее независимо от индексов, но индексы также определенно делают способ 1 существенно быстрее.
Причина этого в том, что индексы разрешают поиск, где в противном случае вам нужно сканирование. Разница между линейным и квадратным законами.