TSQL Почему Top быстрее с переменной?

10

Всем утро,

Я работал над некоторым умеренно сложным SQL, чтобы «получить» некоторые данные из сторонней базы данных продуктов, чтобы отобразить их в наших собственных приложениях.

Я добавил в выборку, чтобы получить верхнюю запись из таблицы в подзапросе (если это имеет смысл)

запрос занял около 3 минут, чтобы вернуть окончательный набор результатов из 100 записей, используя

SELECT TOP 1 ...

Я посмотрел в Интернете, чтобы улучшить то, что я пытался достичь, и было предложено изменить свой выбор, чтобы использовать переменную, как показано ниже

DECLARE @topCount INT
SET @topCount = 1

SELECT TOP (@topCount) ...

Это заняло тот же запрос от 3 минут до 1 секунды, и это здорово!

Но кто-нибудь может объяснить, почему это так.

JamesStuddart
источник

Ответы:

14

Когда вы это сделаете, top 1оптимизатор запросов создаст план, который будет построен так, чтобы получить 1 строку как можно быстрее.

Когда вы используете локальную переменную, ее значение неизвестно оптимизатору, а вместо этого строит план, оптимизированный для получения 100 строк как можно быстрее.

В вашем случае лучше всего использовать план запроса, созданный с целью строки 100, даже если вам нужна только одна строка.

Для проверки вы можете попытаться добавить option (recompile)к вашему запросу переменную. В этом случае SQL Server будет использовать текущее значение @topCountв качестве цели строки, и, поскольку это 1, вы должны получить медленный план.

Микаэль Эрикссон
источник
Я понимаю разницу в плане, но меня удивляет, что выборка 1 строки может быть медленнее, чем выборка 100 строк. Я думаю, что если план из 100 строк работает лучше всего, SQL Server будет использовать тот же план для top 1.
Брэндон
@ Брендон не выбирает 100 строк, а только строит план выполнения с предположением, что 100 строк - это то, что нужно. Выполнение заканчивается, когда найдена 1 строка.
Микаэль Эрикссон
Проверка того, что отличается от плана выполнения в этих случаях, вероятно, поможет понять, в чем проблема с топ-1.
Джеймс З