В чем разница между кластерным и некластерным индексом в SQL?

«В чем разница между кластерным и некластерным индексом в SQL?» — вопрос из категории SQL и базы данных, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Кластерный индекс определяет физический порядок хранения строк данных в таблице. Таблица может иметь только один кластерный индекс, так как данные не могут быть физически упорядочены более чем одним способом. В 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).