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

Поскольку и a, Table Scanи a по 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
20.08.2008 20:38:50
3 ОТВЕТА
РЕШЕНИЕ

В таблице без кластеризованного индекса (таблица кучи) страницы данных не связаны друг с другом - поэтому для обхода страниц требуется поиск в карте распределения индекса .

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

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

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

Так:

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

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

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

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

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

  • INSERT производительность: кластерный индекс выигрывает примерно на 3% благодаря второй записи, необходимой для кучи.
  • UPDATE производительность: кластерный индекс выигрывает примерно на 8% благодаря второму поиску, необходимому для кучи.
  • DELETE производительность: кластерный индекс выигрывает примерно на 18% благодаря необходимому второму поиску и второму удалению из IAM для кучи.
  • единичная SELECTпроизводительность: кластерный индекс выигрывает примерно на 16% благодаря второму поиску, необходимому для кучи.
  • SELECTПроизводительность диапазона : кластерный индекс выигрывает примерно на 29% из-за случайного упорядочения кучи.
  • одновременно INSERT: таблица кучи выигрывает на 30% под нагрузкой из-за разбиения страниц для кластеризованного индекса.
77
15.10.2016 18:49:21
Этот вопрос всплыл у меня в голове сегодня. Спасибо @Terrapin за этот вопрос и спасибо @Marc за хороший ответ!
peakit 1.05.2011 18:53:22
MS Exam 70461 Запросы к Microsoft SQL Server 2012 - Глава 15 Урок 1 имеет углубленное использование.
Yevgraf Andreyevich Zhivago 13.01.2015 23:28:57
Кажется, я не могу получить предполагаемое повышение, указанное в вашем заявлении: «Для запроса с предложением WHERE, который может (хотя бы частично) быть удовлетворен кластеризованным индексом, вы выйдете вперед из-за упорядочения - так что вам не придется сканировать всю таблицу. " У меня есть таблица из 10 миллионов строк. SELECT Id FROM Customer WHERE Id> X выполняется в одно и то же время независимо от того, есть у меня кластеризованный индекс по Id или нет. Как так? Я могу видеть, как это меняется от сканирования таблицы до сканирования кластерного индекса.
Mattias Nordqvist 30.04.2015 07:17:40
@MattiasNordqvist - Если вы просто смотрите на время, вы делаете это неправильно. Из-за кэширования, одновременного доступа, времени процессора и диска и т. Д. Сложно выполнить MS-SQL в одиночку. Загляните в SET STATISTICS IO ON, чтобы проверить, читает ли ваш диск, откуда и начнется повышение. Во-вторых, это будет зависеть от количества возвращаемых строк - если это достаточно высокий процент, оптимизатор мог бы вместо этого выбрать фильтр чтения +.
Mark Brackett 30.04.2015 19:42:44

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

-2
20.08.2008 20:44:58
-1 Это неправильно. Конечный уровень кластеризованного индекса - таблица.
Martin Smith 14.02.2014 19:05:25

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

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

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

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

4
20.08.2008 20:54:30