Увеличивает ли кластерный индекс в столбце внешнего ключа производительность соединения по сравнению с некластеризованным? - PullRequest
6 голосов
/ 12 марта 2010

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

Учитывая, что я забочусь только о том, что выбрано с помощью join, и больше ничего, я ошибаюсь в своем предположении?

Ответы [ 5 ]

9 голосов
/ 12 марта 2010

Обсуждение этого типа вопроса в абсолютном выражении не очень полезно.

Это всегда индивидуальная ситуация!

По существу, доступ через кластеризованный индекс сохраняет одно косвенное указание , точка.

Предполагая, что ключ, используемый в JOIN, является ключом кластеризованного индекса, при одном чтении [неважно, из поиска индекса или из сканирования или частичного сканирования) вы получите всю строку (запись) .

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

Иногда можно получить эквивалентные преимущества кластеризованного индекса с индексом , охватывающего , т. Е. Индекс с нужной последовательностью ключей, после чего следует по интересующим нас значениям столбцов. Как и кластерный индекс, индекс покрытия не требует косвенного обращения к базовой таблице. Действительно, индекс покрытия может быть несколько более эффективным, чем кластерный индекс, потому что он меньше.
Однако, также как и кластеризованные индексы, и помимо затрат на хранение, затраты производительности, связанные с любым дополнительным индексом, во время запросов INSERT (и DELETE или UPDATE) .

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

Чтобы принимать мудрые решения о структуре индекса, нужно

  • чтобы понять, как работают различные типы индексов (и куча)
    (и, кстати, это несколько различается в разных реализациях SQL)
  • , чтобы иметь хорошее изображение статистического профиля базы данных:
    это большие таблицы, которые представляют собой отношения, какова средняя / максимальная мощность отношения, какова типичная скорость роста базы данных и т. д.
  • , чтобы иметь хорошее представление о том, как будут (будут) использоваться / запрашиваться базы данных (ей)

Тогда и только тогда можно сделать обоснованные предположения о заинтересованности [или ее отсутствии] в наличии данного кластерного индекса.

3 голосов
/ 12 марта 2010

Я хотел бы спросить еще кое-что: было бы разумно поместить мой кластерный индекс в столбец внешнего ключа только для ускорения одного соединения? Это, вероятно, помогает, но ..... по цене!

Кластерный индекс делает таблицу быстрее для каждой операции. ДА! Оно делает. См. Превосходную Ким Трипп * Дебаты по кластерным индексам продолжаются для получения дополнительной информации. Она также упоминает свои основные критерии для кластерного индекса:

  • узкая
  • статический (никогда не меняется)
  • уникальный
  • если возможно: постоянно увеличивается

INT IDENTITY отлично справляется с этой задачей, а GUID - нет. См. GUID в качестве первичного ключа для получения дополнительной информации.

Почему сужается? Поскольку ключ кластеризации добавляется к каждой странице индекса каждого и каждого некластеризованного индекса в одной и той же таблице (для того, чтобы иметь возможность фактически искать строку данных, если нужно). Вы не хотите иметь VARCHAR (200) в своем ключе кластеризации ....

Почему уникален ?? См. Выше - ключ кластеризации - это элемент и механизм, который SQL Server использует для уникального поиска строки данных. Это должно быть уникальным. Если вы выберете неуникальный ключ кластеризации, SQL Server сам добавит 4-байтовый уникализатор к вашим ключам. Будьте осторожны с этим!

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

Однако я бы не ни при каких обстоятельствах не поместил бы мой ключ кластеризации на широкий или даже составной внешний ключ. Помните: значения ключа кластеризации добавляются к каждой записи некластеризованного индекса в этой таблице! Если у вас есть 10 некластеризованных индексов, 100 000 строк в вашей таблице - это миллион записей. Это имеет огромное значение, будь то 4-байтовое целое число или 200-байтовый VARCHAR - ОГРОМНЫЙ. И не только на диске, но и в памяти сервера. Тщательно продумайте, как создать кластерный индекс!

SQL Server, возможно, потребуется добавить юниксификатор - что еще хуже. Если значения когда-либо изменятся, SQL Server придется много делать для учета и обновления повсеместно.

Итак, вкратце:

  • индексирование ваших внешних ключей - определенно отличная идея - делайте это постоянно!
  • Я бы очень и очень осторожно отнесся к кластерному индексу. Прежде всего, вы получаете только один кластеризованный индекс, поэтому какие отношения FK вы выберете? И не кладите ключ кластеризации на широкий и постоянно меняющийся столбец
2 голосов
/ 12 марта 2010

Индекс в столбце FK поможет JOIN, потому что сам индекс упорядочен: кластеризованный просто означает, что данные на диске (лист) упорядочены, а не B-дерево.

Если вы измените его на индекс покрытия, то кластеризованный или некластеризованный не имеет значения. Важно иметь полезный индекс.

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

Зависит от реализации базы данных.

Для SQL Server кластеризованный индекс - это структура данных, в которой данные хранятся в виде страниц, а B-деревья хранятся в виде отдельной структуры данных. Причина, по которой вы получаете высокую производительность, заключается в том, что вы можете быстро добраться до начала цепочки, а диапазоны представляют собой простой связанный список.

Некластеризованные индексы - это структура данных, которая содержит указатели на фактические записи и, таким образом, различные проблемы.

См. Документацию, касающуюся Структур кластерного индекса .

Индекс не поможет в отношении отношения внешнего ключа, но он поможет из-за концепции «покрытого» индекса. Если ваше предложение WHERE содержит ограничение, основанное на индексе. он сможет генерировать возвращенный набор данных быстрее. Отсюда и производительность.

0 голосов
/ 12 марта 2010

Повышение производительности обычно происходит, если вы последовательно выбираете данные в кластере. Кроме того, это полностью зависит от размера таблицы (данных) и условий в вашем операторе между.

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