Пожалуйста, объясните план запроса SQL Server выбирает - PullRequest
3 голосов
/ 12 марта 2009

В этой записи блога мне нужно пояснить, почему SQL-сервер выбрал бы определенный тип сканирования:

Давайте для простоты предположим этот col1 уникален и всегда увеличивается в стоимости, col2 имеет 1000 отдельные значения и есть 10 000 000 строк в таблице, и это кластерный индекс состоит из col1, и некластеризованный индекс существует на col2.

Представьте план выполнения запроса изначально создан для следующего переданные параметры: @ P1 = 1 @ P2 = 99

Эти значения приведут к оптимальный план запроса для следующего заявление с использованием замещенного Параметры:

Выберите * из t, где col1> 1 или col2

99 заказ по col1;

Теперь представьте план выполнения запроса если начальные значения параметров были: @ P1 = 6 000 000 и @ P2 = 550.

Как и раньше, оптимальный план запроса быть создан после замены переданные параметры:

Выберите * из t, где col1> 6000000 или col2> 550 заказать по col1;

Эти два идентичных параметризованных SQL Заявления потенциально могут создать и кеш очень разное исполнение планы из-за разницы изначально передаваемые значения параметров. Тем не менее, поскольку SQL Server только кэширует один план выполнения на запрос, шансы очень высоки, что в первом случае план выполнения запроса будет использовать сканирование кластерного индекса из-за «Col1> 1» подстановка параметров. Тогда как во втором случае запрос план выполнения с использованием поиска по индексу будет скорее всего, будет создан.

от: http://blogs.msdn.com/sqlprogrammability/archive/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature.aspx

Почему первый запрос использует кластеризованный индекс, а поиск по индексу во втором запросе?

Ответы [ 3 ]

1 голос
/ 12 марта 2009

В тех случаях, когда оптимизатор видит, что большая часть таблицы будет возвращена в запросе, например, в первом запросе, сканирование будет более эффективным, чем поиск.

Если будет возвращена только небольшая часть таблицы, например, во втором запросе, тогда поиск по индексу более эффективен.

A scan будет касаться каждой строки в таблице независимо от того, подходит она или нет. Стоимость пропорциональна общему количеству строк в таблице. Сканирование является эффективной стратегией, если таблица небольшая или если большинство строк соответствуют предикату.

A seek будет касаться строк, которые соответствуют требованиям, и страниц, которые содержат эти подходящие строки, стоимость пропорциональна количеству соответствующих строк и страниц, а не общему количеству строк в таблице.

1 голос
/ 12 марта 2009

Обратите внимание, что в обоих случаях будет использоваться кластерный индекс. В первом примере это кластеризованный индекс SCAN, где, как во втором примере, это будет кластеризованный индекс SEEK, который в большинстве случаев будет быстрее, как утверждает автор блога.

SQL Server знает, что кластеризованный индекс увеличивается. Поэтому он выполнит сканирование кластерного индекса в первом случае.

1 голос
/ 12 марта 2009

Предполагая, что столбцы содержат только положительные целые числа:

SQL Server будет просматривать статистику для таблицы и видеть, что для первого запроса все строки в таблице соответствуют критериям col1> 1, поэтому он выбирает сканирование кластеризованного индекса.

Для второго запроса относительно небольшая доля строк будет соответствовать критерию col1> 6000000, поэтому использование индекса seek повысит производительность.

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