У меня есть следующий запрос, где Date
имеет данные типа non-nullable date-time
, GroupingId
имеет типа данных non-nullable int
и IsCompleted
имеет данные типа non-nullable tinyint(1)
.
SELECT
*
FROM
Table
WHERE
Date < @TimeNow
AND
GroupingId = @GroupingId
AND
IsCompleted = 0;
У меня есть индекс по этой таблице GroupingId
, Date
, IsCompleted
в таком порядке.
По какой-то причине, если я запускаю этот запрос с помощью t.IsCompleted = 0
, он выполняет намного медленнее, чем t.IsCompleted = 1
каждый раз.
Я думаю, что он не может быть проиндексирован эффективно, но может помочь с ним.
РЕДАКТИРОВАТЬ
Я обновил запрос примера, чтобы сделать его намного яснее. Когда IsCompleted = 0
задано, оно возвращает гораздо меньше строк и занимает намного больше времени, чем когда IsCompleted = 1
установлен
Ваш запрос не может использовать индекс для сортировки. Таким образом, производительность запроса будет определяться по количеству строк, которые соответствуют where
это условию. Предположительно, больше элементов имеет IsCompleted = 0
чем IsCompleted = 1
.
Лучшим индексом для этого запроса является (groupingId, isCompleted, date)
. Первые два ключа могут быть в любом порядке.
Это условие:
((t.Date >= @StartDate AND t.Date < @EndDate) OR (t.Date < @TimeNow))
также немного странно. Я ожидал, что большинство или все даты будут в прошлом. Предполагая, что @TimeNow
представляет что-то вроде текущей даты, это вернет все строки.
IsCompleted = 0
чем IsCompleted = 1
isCompleted
на:groupingId, isCompleted, Date
потому что равенство отбрасывает строки быстрее диапазона при сканировании индекса. На ваш конкретный вопрос проверьте, сколько строк возвращает каждый запрос, когдаisCompleted = 0 / 1
и / или просмотрите план EXPLAIN.IsCompleted = 0
возвращает намного меньше строк, поэтому я запутался, почему эта версия медленнее