2014-01-29 2 views
1

Я использую базу данных SQL Server 2008 R2 с таблицей, которая содержит порядка миллиардов строк. Я хочу, чтобы получить различные значения одного столбца в течение последних 24 часов, так что я сделал это (Запрос 1):Производительность индекса SQL Server, препятствуемая переменной

SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > '2014-01-28 12:24:00' 

Примечания есть индекс по CreatedOn, но он не включает в себя SomeField , Это немедленно вернулось. Теперь, так как это вопрос я часто бег, я решил сделать его динамичным, поэтому я изменил его (запрос 2):

DECLARE @StartDate DATETIME = DATEADD(DAY, -1, GETDATE()) 
SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > @StartDate 

Я был удивлен, что этот запрос занимает много времени. (Я остановил его через минуту или около того.) Затем я попытался положить переменный инлайн как это (Query 3):

SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > DATEADD(DAY, -1, GETDATE()) 

Это было быстро снова. Рассматривая планы выполнения, Query 1 и 3 идентичны и используют Index Seek. Но Query 2 выполняет сканирование индексов и предполагает, что мне не хватает указателя на CreatedOn, включая SomeField.

Почему проверка против переменной внезапно меняет эффективность Индекса?

+1

[Read This] (http://msmvps.com/blogs/robfarley/archive/2010/01/22/sargable-functions-in-sql-server.aspx) для получения дополнительной информации. –

ответ

1

Наиболее вероятная причина в том, что когда значение жестко закодировано, компилятор может использовать статистику для определения наилучшего запроса для запуска. При использовании переменной она не выполняет и должна выполнять сканирование. Вы можете увидеть более высокую производительность, если попытаетесь создать сохраненный процесс, если он и запустит его таким образом, чтобы сервер мог использовать «parameter sniffing».

Дополнительную информацию можно получить у других пользователей, которые видели эту проблему here, here и here.

Смежные вопросы