Sql Excution Plan показывает разные результаты для тех же входов - PullRequest
3 голосов
/ 12 июля 2010
declare @name varchar(156)
set @name ='sara'
--Query 1:
SELECT [PNAME]  FROM [tbltest] where  [PNAME]  like '%'+@name+'%'

--Query 2:
SELECT [PNAME]  FROM [tbltest] where  [PNAME]  like '%sara%'

предположим, что в столбце [PNAME] в [tbltest] есть индекс NoneClustered.при выполнении запросов план Excution показывает индекс Seek For Query 1 и Scan Index для Query 2. я ожидал, что Excution Paln Show Index Scan для обоих запросов, но из-за использования параметра в первом запросе, он покажет индекс поискаТак что же я, мать?в обоих запросах мы использовали «%» на другой стороне и знаем, что в этом состоянии sql не учитывает индекс, но почему в первом плане запроса Query Excetion Plan Show Index Seek?спасибо

Ответы [ 3 ]

1 голос
/ 15 августа 2010

В первом запросе используется параметр, в запросе 2 - константа.

План для запроса 2 не будет повторно использоваться при изменении значения константы.

Запрос для плана 1 может быть. В этом случае SQL Server (просто) оставляет свои параметры открытыми для повторного использования плана.

АКА: запросы не одинаковы.

Если вы принудительно параметризовали , то вы должны заставить оба запроса выполняться как запрос 1. Но я не пробовал ...

0 голосов
/ 15 июля 2010

Я думаю, что Майк находится на правильном пути относительно того, попадаете ли вы в индекс или нет.Ваши последующие действия в отношении затрат могут потребовать большего понимания того, как ваши данные распределяются в таблице.Я видел случаи, когда попадание в индекс обходилось дороже из-за необходимости двух операций чтения с диска.Чтобы понять почему, вам нужно знать, как ваши данные распределяются по индексу, сколько записей помещается на странице и какова ваша схема кэширования.

Я скажу, что это может быть труднонастроить запрос с ведущим%.База данных должна будет полностью пройти ваш индекс (или таблицу) и поразить каждый узел, ища значение, которое содержит «sara».В зависимости от ваших потребностей, вы можете рассмотреть полнотекстовый поиск (т. Е. Используется ли значение параметра в этом запросе, поскольку оно предоставляется как ввод от пользователя вашего приложения).

0 голосов
/ 13 июля 2010

Если вы выполняете DBCC SHOW_STATISTICS для своей таблицы и используемого индекса, ищите «String Index = YES» в первой строке вывода. SQL Server поддерживает некоторую дополнительную статистику для удовлетворения запросов, таких как '% x'

В первом запросе вы, вероятно, увидите вычисленные скалярные значения - посмотрите в плане запроса LikeRangeStart ('%' + @ name + '%'). Индекс поиска против этих значений, в отличие от сканирования индекса против% sara%.

Как это работает, я не знаю. Почему SQL Server не настолько умен, чтобы преобразовать 'sara' в константу и выполнить запрос так же, как я не знаю. Но я думаю, что это происходит.

Против% sara% выполняет сканирование индекса, считывая весь индекс. Для% + @ name +% он создает вычисленные значения RangeStart / RangeEnd / RangeInfo и использует их для поиска индекса, используя преимущества дополнительной статистики строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...