Некластерный индекс и кластерный индекс в одном столбце
Я наткнулся на этот пост в Stackru. В первом ответе упоминается что-то вроде кластеризованного индекса, в котором есть все данные для таблицы, в то время как некластеризованный индекс имеет только столбец + местоположение кластеризованного индекса или строку, если он находится в куче (таблица без кластерного индекса). Как некластеризованный индекс может иметь местоположение кластерного индекса? Он содержит только значения столбца, отсортированные как узлы в B-дереве, причем каждый узел указывает на строку, где столбец имеет это значение узла, верно?
2 ответа
Предполагая, что вы говорите о SQL Server, а также что у вас есть кластеризованный индекс в вашей таблице (как вы должны).
Тогда в некластеризованном индексе есть столбцы, которые вы определили в своем CREATE INDEX
оператор, плюс он имеет столбец (столбцы), которые составляют ваш кластерный индекс (если есть).
Это значение ключа кластеризации является "указателем" на то, где находятся фактические данные.
Если исполнитель запроса ищет в вашем некластеризованном индексе значение и находит совпадение, то
либо это значение - все, что вас волнует - тогда вы просто вернете это значение
или в некластеризованном индексе также могут быть некоторые включенные столбцы (на странице конечного уровня), и с ними запрос может быть выполнен (присутствуют все запрошенные столбцы), так что вы получите значения, которые вы просили
или же нужные значения находятся не на странице конечного уровня некластерного индекса (это особенно верно, если вы
SELECT *
все время), а затем исполнитель запроса должен взять значение ключа кластеризации из некластеризованного индекса и вернуться к индексу кластеризации, выполнить так называемый поиск ключа, выполнить поиск по индексу кластеризации и найти связанную страницу данных, где полная строка сохраняется -> и теперь исполнитель запроса может вернуть запрошенные вами значения
Для довольно хорошего объяснения - см. Этот пост здесь. Это говорит:
В некластеризованном индексе:
....
2.b. Если таблица имеет кластеризованный индекс или индекс находится в индексированном представлении, указатель строки является ключом кластеризованного индекса для строки. SQL Server извлекает строку данных путем поиска в кластеризованном индексе с использованием ключа кластеризованного индекса, хранящегося в строке листьев индекса NonClustered.
Или посмотрите этот пост в целом ряде статей об индексах SQL Server, в которых также объясняются "закладки", хранящиеся на странице уровня некластеризованного индекса.
Это довольно легко представить себе так:
У вас есть таблица клиентов, например, клиент (идентификатор, имя, возраст, адрес). В этой таблице у вас есть кластерный индекс по возрасту. Это означает, что ваши данные отсортированы по возрасту на жестком диске. Это очень полезно для тех случаев, когда вы хотите выполнять диапазонные запросы, такие как:
SELECT * FROM customer WHERE age > 18;
Затем данные могут быть получены с вашего жесткого диска с помощью нескольких последовательных чтений. Если бы индекс был некластеризованным, вам пришлось бы делать один доступ к диску (включая поиск данных) для каждого соответствующего набора клиентов.
Возможно, для вашего приложения вам также необходимо получить доступ к пользователям по идентификатору. Это означает, что без дополнительного индекса по идентификатору вам придется бегать по всему файлу, чтобы найти конкретный идентификатор, потому что он отсортирован по возрасту, а у вас нет индекса! Чтобы избежать этого, вы создаете второй индекс по id. Теперь вы можете искать идентификатор в этом индексе, а лист индекса, который содержит искомого клиента, указывает на место в ваших (по возрасту кластеризованных) данных на диске, где вы найдете кортеж. Таким образом, вы не должны читать всю таблицу, нужно гораздо меньше обращений к диску (в общем случае 2 для поиска по индексу + 1 для извлечения кортежа).
РЕДАКТИРОВАТЬ: я не видел, что вы говорите о той же колонке. Я могу себе представить, что вы делаете один кластерный индекс для одного столбца по причине, описанной выше, и другой комбинированный индекс для этого и другого столбца, например. Это может быть полезно для поиска только по индексу, здесь у вас есть все обязательные атрибуты в индексе и вам вообще не нужно делать выборку страниц. Другой причиной может быть кластеризованный B+-индекс для запросов диапазона и хэш-индекс для запросов на равенство. Но я думаю, что выгода здесь будет незначительной.
Надеюсь, это помогло!