Мне просто любопытно, почему агрегатный запрос выполняется с GROUP BY
предложением гораздо быстрее , чем без него.
Например, этот запрос выполняется почти 10 секунд
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
В то время как этот занимает меньше секунды
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
В CreatedDate
этом случае есть только один , поэтому сгруппированный запрос возвращает те же результаты, что и разгруппированный.
Я заметил, что планы выполнения для этих двух запросов различны - во втором запросе используется параллелизм, а в первом - нет.
Является ли нормальным для SQL-сервера оценивать агрегатный запрос по-другому, если у него нет предложения GROUP BY? И есть ли что-то, что я могу сделать, чтобы улучшить производительность 1-го запроса без использования GROUP BY
предложения?
редактировать
Я только что узнал, что могу использовать OPTION(querytraceon 8649)
для установки издержек параллелизма на 0, что заставляет запрос использовать некоторый параллелизм и сокращает время выполнения до 2 секунд, хотя я не знаю, есть ли какие-либо недостатки в использовании этой подсказки запроса.
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
OPTION(querytraceon 8649)
Я бы все же предпочел более короткое время выполнения, поскольку запрос предназначен для заполнения значения при выборе пользователя, поэтому в идеале он должен быть мгновенным, как сгруппированный запрос. Прямо сейчас я просто завершаю свой запрос, но я знаю, что это не идеальное решение.
SELECT Min(CreatedDate)
FROM
(
SELECT Min(CreatedDate) as CreatedDate
FROM MyTable WITH (NOLOCK)
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
) as T
Редактировать № 2
В ответ на запрос Мартина о дополнительной информации :
Оба CreatedDate
и SomeIndexedValue
имеют отдельный неуникальный некластеризованный индекс. SomeIndexedValue
на самом деле это поле varchar (7), хотя оно хранит числовое значение, указывающее на PK (int) другой таблицы. Связь между двумя таблицами не определена в базе данных. Я не должен изменять базу данных вообще, и могу только писать запросы, которые запрашивают данные.
MyTable
содержит более 3 миллионов записей, и каждой записи присваивается группа, к которой она принадлежит ( SomeIndexedValue
). В группах может быть от 1 до 200 000 записей
MAXDOP
устанавливает максимальную степень параллелизма, которая ограничивает число процессоров, которые может использовать запрос. Это в основном заставит второй запрос работать так же медленно, как и первый, поскольку он удаляет возможности использовать параллелизм, а это не то, что мне нужно.