Что на самом деле означает Кластерный и Некластерный индекс? - PullRequest
960 голосов
/ 09 августа 2009

У меня ограниченная доступность БД, и я использовал только БД в качестве прикладного программиста. Я хочу знать о Clustered и Non clustered indexes. Я гуглил и нашел:

Кластерный индекс - это особый тип индекса, который переупорядочивает способ записи в таблице физически сохраняются. Поэтому таблица может иметь только один кластерный индекс. Листовые узлы кластерного индекса содержат данные страницы. Некластеризованный индекс особый тип индекса, в котором логический порядок индекса не соответствовать физическому сохраненному порядку строки на диске. Листовой узел некластеризованный индекс не состоит из страницы данных. Вместо этого лист узлы содержат строки индекса.

То, что я нашел в SO, было В чем различия между кластерным и некластеризованным индексом? .

Может кто-нибудь объяснить это простым английским языком?

Ответы [ 10 ]

963 голосов
/ 09 августа 2009

При кластеризованном индексе строки физически хранятся на диске в том же порядке, что и индекс. Следовательно, может быть только один кластерный индекс.

С некластеризованным индексом существует второй список, в котором есть указатели на физические строки. У вас может быть много некластеризованных индексов, хотя каждый новый индекс будет увеличивать время, необходимое для записи новых записей.

Как правило, быстрее читать из кластерного индекса, если вы хотите получить обратно все столбцы. Вам не нужно идти сначала к индексу, а затем к таблице.

Запись в таблицу с кластеризованным индексом может быть медленнее, если необходимо переставить данные.

566 голосов
/ 09 августа 2009

Кластерный индекс означает, что вы говорите базе данных хранить близкие значения, фактически близкие друг к другу на диске. Это дает преимущество быстрого сканирования / извлечения записей, попадающих в некоторый диапазон значений кластеризованного индекса.

Например, у вас есть две таблицы: Клиент и Заказ:

Customer
----------
ID
Name
Address

Order
----------
ID
CustomerID
Price

Если вы хотите быстро получить все заказы одного конкретного клиента, вы можете создать кластеризованный индекс в столбце «CustomerID» таблицы «Заказы». Таким образом, записи с одинаковым CustomerID будут физически храниться близко друг к другу на диске (кластеризованно), что ускоряет их поиск.

P.S. Индекс для CustomerID, очевидно, будет не уникальным, поэтому вам нужно либо добавить второе поле для «унификации» индекса, либо позволить базе данных обработать это для вас, но это уже другая история.

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

272 голосов
/ 28 июня 2014

В хранилище, ориентированном на строки в SQL Server, как кластерные, так и некластеризованные индексы организованы в виде деревьев B.

enter image description here

( Источник изображения )

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

  1. Строки на листовых страницах кластеризованного индекса всегда содержат что-то для каждого (не разреженного) столбца в таблице (либо значение, либо указатель на фактическое значение).
  2. Кластерный индекс является основной копией таблицы.

Некластеризованные индексы также могут выполнить пункт 1, используя предложение INCLUDE (начиная с SQL Server 2005) для явного включения всех неключевых столбцов, но они являются вторичными представлениями, и всегда есть другая копия данных (сама таблица) ).

CREATE TABLE T
(
A INT,
B INT,
C INT,
D INT
)

CREATE UNIQUE CLUSTERED INDEX ci ON T(A,B)
CREATE UNIQUE NONCLUSTERED INDEX nci ON T(A,B) INCLUDE (C,D)

Два индекса выше будут почти идентичны. С индексными страницами верхнего уровня, содержащими значения для ключевых столбцов A,B, и страницами конечного уровня, содержащими A,B,C,D

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

Приведенная выше цитата из книг по SQL Server в Интернете вызывает большую путаницу

На мой взгляд, это было бы гораздо лучше сформулировать как.

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

Книжная онлайн-цитата не является неправильной, но вы должны понимать, что «сортировка» как некластеризованных, так и кластеризованных индексов является логической, а не физической Если вы читаете страницы на уровне листа, следуя связанному списку, и читаете строки на странице в порядке расположения слотов, то вы будете читать строки индекса в отсортированном порядке, но физически страницы могут быть не отсортированы. Обычно считается, что при кластеризованном индексе строки всегда физически хранятся на диске в том же порядке, что и индекс key , неверно.

Это было бы абсурдной реализацией. Например, если строка вставлена ​​в середину таблицы 4 ГБ, SQL Server не должен скопировать 2 ГБ данных в файл, чтобы освободить место для вновь вставленной строки.

Вместо этого происходит разделение страницы. Каждая страница на уровне листьев как кластеризованных, так и некластеризованных индексов имеет адрес (File:Page) следующей и предыдущей страниц в порядке логического ключа. Эти страницы не обязательно должны быть смежными или в ключевом порядке.

например. цепочка связанных страниц может быть 1:2000 <-> 1:157 <-> 1:7053

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

Степень, в которой логический порядок и смежность отличаются от идеализированной физической версии, является степенью логической фрагментации.

Во вновь созданной базе данных с одним файлом я запустил следующее.

CREATE TABLE T
  (
     X TINYINT NOT NULL,
     Y CHAR(3000) NULL
  );

CREATE CLUSTERED INDEX ix
  ON T(X);

GO

--Insert 100 rows with values 1 - 100 in random order
DECLARE @C1 AS CURSOR,
        @X  AS INT

SET @C1 = CURSOR FAST_FORWARD
FOR SELECT number
    FROM   master..spt_values
    WHERE  type = 'P'
           AND number BETWEEN 1 AND 100
    ORDER  BY CRYPT_GEN_RANDOM(4)

OPEN @C1;

FETCH NEXT FROM @C1 INTO @X;

WHILE @@FETCH_STATUS = 0
  BEGIN
      INSERT INTO T (X)
      VALUES        (@X);

      FETCH NEXT FROM @C1 INTO @X;
  END

Затем проверил макет страницы с помощью

SELECT page_id,
       X,
       geometry::Point(page_id, X, 0).STBuffer(1)
FROM   T
       CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
ORDER  BY page_id

Результаты были повсюду. Первая строка в ключевом порядке (со значением 1 - выделено стрелкой ниже) была почти на последней физической странице.

enter image description here

Фрагментация может быть уменьшена или удалена путем перестройки или реорганизации индекса для увеличения корреляции между логическим порядком и физическим порядком.

После запуска

ALTER INDEX ix ON T REBUILD;

Я получил следующее

enter image description here

Если таблица не имеет кластеризованного индекса, она называется кучей.

Некластеризованные индексы могут быть построены либо на куче, либо на кластерном индексе. Они всегда содержат локатор строк обратно к базовой таблице. В случае кучи это физический идентификатор строки (rid) и состоит из трех компонентов (File: Page: Slot). В случае кластеризованного индекса указатель строки является логическим (ключ кластеризованного индекса).

В последнем случае, если некластеризованный индекс уже включает столбцы ключа CI либо в виде столбцов ключа NCI, либо в столбцы INCLUDE -d, то ничего не добавляется. В противном случае недостающие столбцы ключа CI автоматически добавляются в NCI.

SQL Server всегда гарантирует, что ключевые столбцы уникальны для обоих типов индекса. Механизм, в котором это применяется для индексов, не объявленных как уникальные, отличается между двумя типами индексов.

Кластеризованным индексам добавляется uniquifier для любых строк со значениями ключей, которые дублируют существующую строку. Это просто восходящее целое число.

Для некластеризованных индексов, не объявленных как уникальные, SQL Server автоматически добавляет локатор строк в ключ некластеризованного индекса. Это относится ко всем строкам, а не только к тем, которые на самом деле являются дубликатами.

Кластеризованная и некластерная номенклатура также используется для индексов хранилища столбцов. Документ Усовершенствования хранилищ столбцов SQL Server состояния

Хотя данные хранилища столбцов на самом деле не «кластеризованы» ни по одному ключу, мы решил сохранить традиционное соглашение SQL Server о ссылках к первичному индексу как кластерному индексу.

119 голосов
/ 27 октября 2016

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

КЛАСТЕРНЫЙ ИНДЕКС

Если вы войдете в публичную библиотеку, вы обнаружите, что все книги расположены в определенном порядке (скорее всего, десятичная система Дьюи, или DDS). Это соответствует «кластерному индексу» книг. Если бы DDS # для нужной вам книги был 005.7565 F736s, вы бы начали с поиска строки книжных полок с надписью 001-099 или чего-то подобного. (Этот знак конца колпачка в конце стека соответствует «промежуточному узлу» в индексе.) В конце концов, вам нужно перейти к определенной полке, помеченной 005.7450 - 005.7600, а затем сканировать, пока не найдете книгу с указанным DDS # и в этот момент вы нашли свою книгу.

НЕКЛАСТЕРНЫЙ ИНДЕКС

Но если вы не вошли в библиотеку с запоминанием DDS # вашей книги, вам понадобится второй указатель, чтобы помочь вам. В старину перед библиотекой находилось замечательное бюро ящиков, известное как «Каталог карт». В нем были тысячи карточек 3х5 - по одной на каждую книгу, отсортированные в алфавитном порядке (возможно, по названию). Это соответствует «некластеризованному индексу» . Эти каталоги карточек были организованы в иерархическую структуру, так что каждый ящик был помечен диапазоном карточек, которые он содержал (например, Ka - Kl; то есть «промежуточный узел»). Еще раз, вы будете углубляться до тех пор, пока не найдете свою книгу, но в этом случае, как только вы нашли ее (т. Е. «Листовой узел»), у вас нет самой книги, а просто карта с номером index (DDS #), с которой вы можете найти фактическую книгу в кластерном индексе.

Конечно, ничто не помешает библиотекарю фотокопировать все карточки и сортировать их в другом порядке в отдельном каталоге карточек. (Обычно таких каталогов было как минимум два: один отсортирован по имени автора, а другой по названию.) В принципе, вы можете иметь столько «некластеризованных» индексов, сколько захотите.

66 голосов
/ 21 января 2013

Найдите ниже некоторые характеристики кластерных и некластеризованных индексов:

Кластерные индексы

  1. Кластерные индексы - это индексы, которые однозначно идентифицируют строки в таблице SQL.
  2. Каждая таблица может иметь ровно один кластерный индекс.
  3. Вы можете создать кластерный индекс, который охватывает более одного столбца. Например: create Index index_name(col1, col2, col.....).
  4. По умолчанию столбец с первичным ключом уже имеет кластеризованный индекс.

Некластеризованные индексы

  1. Некластеризованные индексы похожи на простые индексы. Они просто используются для быстрого поиска данных. Не уверен, что у вас есть уникальные данные.
46 голосов
/ 09 августа 2009

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

24 голосов
/ 21 января 2018

Кластерный индекс

Кластерный индекс определяет физический порядок данных в таблице. По этой причине таблица имеет только 1 кластерный индекс.

как "словарь" Нет необходимости в каком-либо другом индексе, его индекс уже соответствует словам

Некластеризованный индекс

Некластеризованный индекс аналогичен индексу в Книге. Данные хранятся в одном месте. Индекс хранится в другом месте, и у индекса есть указатели на место хранения данных. По этой причине таблица имеет более 1 некластеризованного индекса.

как и в «Книге химии» при взгляде, есть отдельный указатель для указания местоположения главы, а в «КОНЕЦ» есть еще один указатель, указывающий общее местоположение СЛОВ

4 голосов
/ 28 августа 2017

Кластерный индекс

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

Единственный раз, когда строки данных в таблице хранятся в отсортированном порядке, это когда таблица содержит кластеризованный индекс. Когда таблица имеет кластеризованный индекс, она называется кластерной таблицей. Если таблица не имеет кластеризованного индекса, ее строки данных хранятся в неупорядоченной структуре, называемой кучей.

Некластеризованный

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

Вы можете добавить неключевые столбцы на конечный уровень некластеризованного индекса, чтобы обойти существующие ограничения ключа индекса и выполнить полностью покрытые, проиндексированные запросы. Для получения дополнительной информации см. Создание индексов с включенными столбцами. Подробные сведения об ограничениях ключа индекса см. В разделе Характеристики максимальной емкости для SQL Server.

Ссылка: https://docs.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described

1 голос
/ 09 декабря 2018

Позвольте мне предложить определение учебника по «индексу кластеризации», которое взято из 15.6.1 из Системы баз данных: Полная книга :

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

Чтобы понять определение, давайте взглянем на пример 15.10, представленный в учебнике:

Отношение R(a,b), которое сортируется по атрибуту a и сохраняется в нем порядок, упакованный в блоки, обязательно кластеризован. Индекс на a является индекс кластеризации, так как для данного a -значения a1 все кортежи с это значение для a является последовательным. Таким образом, они выглядят упакованными в блоки, кроме, возможно, для первого и последнего блоков, которые содержат a -значение a1, как показано на рис.15.14. Тем не менее, индекс на б вряд ли будет кластеризация, так как кортежи с фиксированным значением b будет распространяться по всему файлу, если значения a и b не очень тесно связаны.

Fig 15.14

Обратите внимание, что определение не требует, чтобы блоки данных были смежными на диске; он только говорит, что кортежи с ключом поиска упакованы в как можно меньше блоков данных.

Связанное понятие кластеризованное отношение . Отношение «кластеризовано», если его кортежи упакованы примерно в несколько блоков, которые могут содержать эти кортежи. Другими словами, с точки зрения дискового блока, если он содержит кортежи из разных отношений, то эти отношения не могут быть кластеризованы (т. Е. Существует более упакованный способ хранения такого отношения путем замены кортежей этого отношения из других дисковых блоков с помощью кортежи не принадлежат отношению в текущем блоке диска). Ясно, что R(a,b) в приведенном выше примере является кластеризованным.

Чтобы связать две концепции вместе, кластеризованное отношение может иметь индекс кластеризации и индекс некластеризации. Однако для некластеризованного отношения кластеризация индекса невозможна, если индекс не построен поверх первичного ключа отношения.

«Кластер» как слово является спамом на всех уровнях абстракции на стороне хранилища базы данных (три уровня абстракции: кортежи, блоки, файл). Концепция под названием « кластеризованный файл », которая описывает, содержит ли файл (абстракция для группы блоков (один или несколько дисковых блоков)) кортежи из одного отношения или различных отношений. Это не относится к концепции индекса кластеризации, как на уровне файлов.

Однако, некоторые учебные материалы любят определять индекс кластеризации на основе определения кластеризованного файла. Эти два типа определений одинаковы на уровне кластеризованных отношений, независимо от того, определяют ли они кластеризованные отношения в терминах блока данных или файла. По ссылке в этом абзаце

Индекс для атрибута (ов) A в файле является индексом кластеризации, когда: Все кортежи со значением атрибута A = a сохраняются последовательно (= последовательно) в файле данных

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

1 голос
/ 19 ноября 2018

Кластерный индекс: Ограничение первичного ключа создает кластеризованный индекс автоматически, если в таблице не существует кластеризованного индекса. Фактические данные кластерного индекса могут храниться на уровне листа индекса.

Некластерный индекс: Фактические данные некластеризованного индекса непосредственно не обнаруживаются на конечном узле, вместо этого необходимо выполнить дополнительный шаг для поиска, поскольку в нем есть только значения локаторов строк, указывающие на фактические данные. Некластерный индекс не может быть отсортирован как кластерный индекс. В одной таблице может быть несколько некластеризованных индексов, на самом деле это зависит от используемой нами версии сервера SQL. В основном Sql server 2005 допускает 249 некластеризованных индексов, а для вышеприведенных версий, таких как 2008, 2016, он допускает 999 некластеризованных индексов на таблицу.

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