Ответ
Кластерный индекс определяет физический порядок хранения строк данных в таблице. Таблица может иметь только один кластерный индекс, так как данные не могут быть физически упорядочены более чем одним способом. В SQL Server и MySQL (InnoDB) первичный ключ по умолчанию создает кластерный индекс.
Некластерный индекс — это отдельная структура, которая хранит отсортированные ключевые значения вместе с указателями на фактические строки данных (row locators). На одну таблицу можно создать множество некластерных индексов.
Ключевые различия:
| Аспект | Кластерный индекс | Некластерный индекс |
|---|---|---|
| Количество | Один на таблицу | Множество на таблицу |
| Структура | Данные таблицы физически отсортированы | Отдельная структура (B-дерево) с указателями |
| Скорость чтения | Быстрее для диапазонных запросов и поиска по первичному ключу | Быстрее для точечных запросов по индексируемым полям |
| Скорость вставки | Медленнее (требуется переупорядочивание) | Быстрее (добавляется только запись в индекс) |
| Хранение | Содержит сами данные | Содержит ключи + указатели на данные |
Примеры в SQL:
-- Создание таблицы с кластерным индексом (первичный ключ)
CREATE TABLE Orders (
OrderID INT PRIMARY KEY, -- Создает кластерный индекс
CustomerID INT,
OrderDate DATE,
Amount DECIMAL(10,2)
);
-- Создание некластерного индекса
CREATE NONCLUSTERED INDEX IX_Orders_CustomerID
ON Orders(CustomerID);
-- Составной некластерный индекс
CREATE NONCLUSTERED INDEX IX_Orders_Date_Customer
ON Orders(OrderDate DESC, CustomerID);
Практический опыт: В проектах с высокой нагрузкой на запись я тщательно проектирую кластерный индекс, чтобы минимизировать фрагментацию. Для часто запрашиваемых полей, не входящих в кластерный индекс, создаю покрывающие некластерные индексы (covering indexes), которые включают все необходимые для запроса столбцы, чтобы избежать обращений к самой таблице (key lookups).