В чем разница между сканированием таблицы и сканированием кластеризованного индекса? - PullRequest
68 голосов
/ 21 августа 2008

Поскольку и 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

Ответы [ 3 ]

77 голосов
/ 21 августа 2008

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

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

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

И, конечно же, кластеризованный индекс позволяет вам выполнять КЛЕСТЕРНЫЙ ПОИСК ИНДЕКСА, который в значительной степени оптимален для производительности ... куча без индексов всегда приведет к сканированию таблицы.

Итак:

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

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

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

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

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

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

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 :(), возвращаются только те строки, которые удовлетворяют предикату.

0 голосов
/ 21 августа 2008

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

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