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

StackOverflow https://stackoverflow.com/questions/18764

  •  09-06-2019
  •  | 
  •  

Вопрос

Поскольку оба a 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
Это было полезно?

Решение

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

Однако кластеризованная таблица содержит страницы данных, связанные в виде двусвязного списка - выполнение последовательных сканирований немного быстрее.Конечно, в обмен на это у вас возникают накладные расходы по поддержанию порядка страниц данных на 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% при загрузке из-за разделения страниц для кластеризованного индекса.

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top