Мені просто цікаво, чому сукупний запит працює так швидше з 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
встановлює максимальний ступінь паралелізму, який обмежує кількість процесорів, які запит може використовувати. Це, в основному, зробить другий запит так само повільним, як і перший, оскільки він видаляє його можливості використовувати паралелізм, який не є тим, що я хочу.