Что такое кластерный индекс в базах данных?

Ответ

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

Ключевые особенности:

  • Физическое упорядочивание: Строки в таблице хранятся на диске в порядке, заданном ключом кластерного индекса.
  • Первичный ключ: В SQL Server и некоторых других СУБД создание первичного ключа (PRIMARY KEY) по умолчанию приводит к созданию кластерного индекса, если он еще не существует.
  • Скорость запросов: Запросы, использующие диапазон значений по ключу кластерного индекса (WHERE id BETWEEN 10 AND 100), выполняются очень быстро, так как данные физически расположены рядом.

Пример создания в SQL Server:

-- Создание таблицы с кластерным индексом по полю OrderID
CREATE TABLE Orders (
    OrderID INT NOT NULL PRIMARY KEY CLUSTERED, -- PRIMARY KEY создает кластерный индекс
    CustomerID INT,
    OrderDate DATETIME
);
-- ИЛИ явное создание после создания таблицы
CREATE CLUSTERED INDEX IX_Orders_OrderDate ON Orders(OrderDate);
Сравнение с некластерным индексом: Аспект Кластерный индекс Некластерный индекс
Количество Один на таблицу Много на таблицу
Содержимое Содержит сами данные таблицы Содержит ключ + указатель на строку данных
Скорость выборки Максимальная для диапазонных запросов Быстрее, чем полное сканирование, но медленнее кластерного
Влияние на INSERT/UPDATE Может быть медленнее, так как требует переупорядочивания данных Обычно быстрее, так как обновляется только структура индекса

Практические рекомендации:

  • Выбирайте для кластеризации столбец, который часто используется в запросах диапазонов (BETWEEN, >, <) или ORDER BY.
  • Хорошие кандидаты: монотонно возрастающие ключи (например, IDENTITY), часто используемые в соединениях.
  • Избегайте кластеризации по часто изменяемым столбцам или столбцам с большим размером, так как это приведет к постоянной физической реорганизации данных (фрагментации).

Ответ 18+ 🔞

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

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

Что это за зверь и с чем его едят:

  • Это и есть сама таблица. Ключ индекса — это порядок, в котором листы лежат в папке. Нашел нужную дату — сразу взял лист с данными.
  • Первичный ключ — его лучший друг. В SQL Server, как только ты объявляешь PRIMARY KEY, система по умолчанию тупо делает его кластерным индексом. Если, конечно, ты ей не запретил.
  • Скорость — его конёк. Нужны все заказы за июль? Пфф, открыл папку, взял стопку листов за этот месяц — и готово. Потому что они лежат рядом. Это охуенно быстро.

Вот как его наколдовать:

-- Вариант раз: сразу при рождении таблицы
CREATE TABLE Orders (
    OrderID INT NOT NULL PRIMARY KEY CLUSTERED, -- Всё, OrderID теперь царь и бог порядка
    CustomerID INT,
    OrderDate DATETIME
);

-- Вариант два: если охуел и передумал, можно потом
CREATE CLUSTERED INDEX IX_Orders_OrderDate ON Orders(OrderDate);
-- Теперь таблица пересортирована по дате заказа. Старый порядок — в пизду.

Чем он не похож на своего младшего брата — некластерный индекс:

Вопрос на засыпку Кластерный индекс (Царь) Некластерный индекс (Прислуга)
Сколько их можно? Один, пиздец. Больше нельзя. Да хоть сотню, если хватит места на диске.
А что внутри? Да сами данные таблицы, ёпта! Ключ для поиска + адресок, где искать в куче данных.
Как быстро находит? Молниеносно, если ищешь по диапазону. Быстрее, чем рыться в свалке, но всё равно надо сходить по адресу.
А если вставить новое? Может быть больно. Придется вставлять лист в нужное место, сдвигая остальные. Проще. Кинул новую запись куда попало, а в индекс добавил просто новую ссылочку.

Главное, что надо запомнить, чтобы не выстрелить себе в ногу:

  • Кластеризуй по тому, что часто ищешь диапазонами (WHERE date BETWEEN ..., ORDER BY). Идеально — столбец с автоинкрементом (IDENTITY).
  • НЕ кластеризуй по тому, что постоянно меняется. Представь, ты переименовал клиента, а из-за этого всю папку надо перетряхивать. Фрагментация будет — овердохуища, а производительность — в жопу.
  • И уж тем более не делай кластерный индекс по полю с длинным-предлинным текстом. Это просто самоубийство, чувак.