В чем разница между сканированием таблиц и сканированием индексов кластеров?


63

Поскольку и Table Scan, и Clustered Index Scan, по существу, сканируют все записи в таблице, почему сканирование с помощью кластерного индекса кажется лучше?

В качестве примера - что разница в производительности между следующими когда есть много записей ?:

declare @temp table(
    SomeColumn varchar(50) 
) 

insert into @temp 
select 'SomeVal' 

select * from @temp 

----------------------------- 

declare @temp table(
    RowID int not null identity(1,1) primary key, 
    SomeColumn varchar(50) 
) 

insert into @temp 
select 'SomeVal' 

select * from @temp 
70

В таблице без кластеризованного индекса (таблица кучи) страницы данных не связаны друг с другом - для перемещения страниц требуется lookup into the Index Allocation Map.

У кластеризованного стола, однако, есть data pages linked in a doubly linked list - выполнение последовательных сканов немного быстрее. Конечно, взамен, у вас есть накладные расходы на то, чтобы держать страницы данных в порядке по INSERT, UPDATE и DELETE. Однако в таблице кучи требуется вторая запись в IAM.

Если запрос имеет RANGE оператора (например .: SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100), а затем кластерную таблицу (будучи в гарантированном порядке) будет более эффективным - как он может использовать индексные страницы, чтобы найти нужную страницу (ы) данных. Куча должна будет сканировать все строки, поскольку она не может полагаться на упорядочение.

И, конечно же, кластеризованный индекс позволяет выполнять CLUSTERED INDEX SEEK, что в значительной степени оптимально для производительности ... куча без индексов всегда приведет к сканированию таблицы.

Итак:

  • Для вашего примера запроса, где надо выбрать все строки, единственное отличие состоит в двусвязном списке кластерный индекс поддерживает. Это должно сделать вашу кластерную таблицу чуть-чуть быстрее, чем куча с большим количеством строк.

  • Для запроса с предложением WHERE, которое может быть (по крайней мере частично) удовлетворено кластеризованным индексом, вы выйдете вперед из-за заказа - так что вам не придется сканировать всю таблицу.

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

  • Для INSERT, UPDATE и DELETE куча может или не может быть выиграна. Куча не должна поддерживать порядок, но требует второй записи для IAM. Я думаю, что относительная разница в производительности будет незначительной, но также очень зависимой от данных.

Microsoft имеет whitepaper, который сравнивает кластерный индекс к эквивалентному без кластерного индекса на куче (не точно так же, как мы обсуждали выше, но близко к этому). Их вывод состоит в том, чтобы поместить кластеризованный индекс во все таблицы. Я сделаю все возможное, чтобы суммировать свои результаты (опять же, обратите внимание, что на самом деле они сравнивают некластеризованную индекс к кластерному индексу здесь - но я думаю, что это относительно сопоставимого):

  • INSERT производительности: кластерный индекс выигрывает около 3% из-за второй записи, необходимой для кучи.
  • UPDATE производительность: кластеризованный индекс выигрывает примерно на 8% из-за второго поиска, необходимого для кучи.
  • DELETE производительность: кластеризованный индекс выигрывает примерно на 18% из-за необходимости второго поиска и второго удаления, необходимого из IAM для кучи.
  • single SELECT производительность: сгруппированный индекс выигрывает примерно на 16% из-за второго поиска, необходимого для кучи.
  • диапазон SELECT производительность: сгруппированный индекс выигрывает примерно на 29% из-за случайного упорядочения для кучи.
  • concurrent INSERT: таблица кучи выигрывает на 30% под нагрузкой из-за разбиения страницы на кластерный индекс.
+1

Этот вопрос сегодня взволнован. Спасибо @Terrapin за это и спасибо @Marc за то, что он так хорошо ответил! 01 май. 112011-05-01 18:53:22

+1

MS экзамен 70461 Запрос Microsoft SQL Server 2012 - Глава 15 Урок 1 имеет углубленное использование. 13 янв. 152015-01-13 23:28:57

  0

Я, похоже, не могу получить предполагаемый импульс, указанный вашим утверждением: «Для запроса с предложением WHERE, которое может быть (по крайней мере частично) удовлетворено кластеризованным индексом, вы выйдете вперед из-за заказа - так что вам не придется сканировать всю таблицу ». У меня таблица из 10 миллионов строк. SELECT Id FROM Customer WHERE Id> X выполняется за тот же промежуток времени независимо от того, есть ли у меня кластерный индекс в Id или нет. Как так? Однако я вижу, как он изменяется от сканирования таблицы к кластерному сканированию индекса. 30 апр. 152015-04-30 07:17:40

+2

@ MattiasNordqvist - Если вы просто смотрите на время, вы делаете это неправильно. Из-за кеширования, одновременного доступа, процессора и времени на диске и т. Д. Сложно выполнить настройку MS-SQL только в одно время. Посмотрите в SET STATISTICS IO ON, чтобы проверить, читает ли ваш диск, откуда будет происходить повышение. Во-вторых, это будет зависеть от количества возвращенных строк - если это достаточно высокий процент, оптимизатор может, по-видимому, выбрать вместо этого фильтр чтения +. 30 апр. 152015-04-30 19:42:44


-2

таблица сканирования изучить каждую строку таблицы. Для сканирования кластерного индекса требуется только сканирование индекса. Он не проверяет каждую запись в таблице. В этом-то и дело, индексы.

+7

-1 Это неправильно. Уровень листа кластерного индекса * - это таблица. 14 фев. 142014-02-14 19:05:25


4

http://msdn.microsoft.com/en-us/library/aa216840(SQL.80).aspx

кластерного индекса сканирования логический и физический оператор сканирует кластерный индекс, указанный в столбце аргумента. Когда присутствует дополнительный предикат WHERE :(), возвращаются только те строки, которые удовлетворяют предикату. Если столбец «Аргумент» содержит предложение ORDERED, процессор запросов запросил, чтобы вывод строк возвращался в том порядке, в котором кластеризованный индекс отсортировал их. Если предложение ORDERED отсутствует, механизм хранения сканирует индекс оптимальным образом (не гарантируя сортировку вывода).

http://msdn.microsoft.com/en-us/library/aa178416(SQL.80).aspx

В таблице сканирования логический и физический оператор извлекает все строки из таблицы, указанной в столбце аргумента. Если в столбце Аргумент появляется предикат WHERE :(), возвращаются только те строки, которые удовлетворяют предикату.