← Назад к вопросам

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

2.0 Middle🔥 251 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Это вопрос о структурах данных в базах данных (SQL Server, PostgreSQL, MySQL). Индексы — это ключевые структуры для оптимизации производительности запросов.

Кластеризованный индекс (Clustered Index)

Определение: кластеризованный индекс определяет физический порядок сортировки строк в таблице. В каждой таблице может быть только один кластеризованный индекс.

Структура:

  • Листовые узлы содержат сами данные (data pages) таблицы
  • Порядок сортировки данных на диске соответствует порядку индекса
  • Это как содержание книги — порядок глав соответствует структуре
-- Пример создания кластеризованного индекса
CREATE CLUSTERED INDEX IX_User_Id 
ON Users(Id) -- Primary key часто задаёт кластеризованный индекс

CREATE CLUSTERED INDEX IX_Orders_UserId 
ON Orders(UserId);

Производительность:

  • Быстрый поиск диапазонов (range queries): WHERE id BETWEEN 100 AND 200
  • Эффективен при сортировке: ORDER BY id
  • Группировка: GROUP BY id
  • Один поиск может вернуть много строк подряд

Некластеризованный индекс (Non-Clustered Index)

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

Структура:

  • Листовые узлы содержат ключи индекса + указатель на строку (row locator)
  • Указатель либо на кластеризованный ключ, либо на физический адрес (heap)
  • Это как предметный указатель в книге — указывает на страницы, но не меняет порядок
-- Примеры некластеризованных индексов
CREATE NONCLUSTERED INDEX IX_User_Email 
ON Users(Email);

CREATE NONCLUSTERED INDEX IX_Order_Date 
ON Orders(OrderDate);

-- Индекс с включёнными колонками (covering index)
CREATE NONCLUSTERED INDEX IX_Order_Status 
ON Orders(Status) 
INCLUDE (TotalAmount, CustomerName);

Производительность:

  • Быстрый поиск конкретных значений
  • Поддержка covering index (все данные в индексе, без обращения к таблице)
  • Может быть несколько — выбираем оптимальный

Сравнительная таблица

ХарактеристикаКластеризованныйНекластеризованный
Количество на таблицуТолько 1До 999
Физический порядокОпределяетНе влияет
Листовые узлыСодержат данныеСодержат ключи + указатели
Диапазонные запросыОчень быстроТребует дополнительных обращений
ОбновлениеЗатратно (переупорядочивание)Менее затратно
РазмерЗанимает место данныхДополнительное место

Практический пример

-- Таблица Users
CREATE TABLE Users (
    Id INT PRIMARY KEY CLUSTERED, -- Кластеризованный индекс по Id
    Email NVARCHAR(100) NOT NULL,
    Name NVARCHAR(100),
    CreatedDate DATETIME
);

-- Добавляем некластеризованный индекс для быстрого поиска по Email
CREATE NONCLUSTERED INDEX IX_Email ON Users(Email);

-- Запрос 1: использует кластеризованный индекс
SELECT * FROM Users WHERE Id = 42;
-- Быстро: прямой поиск по кластеризованному индексу

-- Запрос 2: использует некластеризованный индекс
SELECT * FROM Users WHERE Email = "john@example.com";
-- Быстро: поиск в IX_Email, затем переход по указателю на данные

-- Запрос 3: range query
SELECT * FROM Users WHERE Id BETWEEN 1 AND 100 ORDER BY Id;
-- Очень быстро: кластеризованный индекс возвращает последовательные строки

Влияние на производительность Java-приложения

В контексте Java разработчик должен знать:

// Плохой запрос (полный scan без индекса)
List<User> users = session.createQuery(
    "SELECT u FROM User u WHERE u.email = :email"
).setParameter("email", email).list();
// Без индекса будет сканироваться вся таблица

// Хороший запрос (с индексом)
List<User> users = session.createQuery(
    "SELECT u FROM User u WHERE u.id = :id"
).setParameter("id", id).list();
// Использует кластеризованный индекс по Primary Key

Итог

  • Кластеризованный — определяет физический порядок, один на таблицу, лучше для диапазонов
  • Некластеризованный — отдельная структура, много на таблицу, лучше для конкретных значений
  • Выбор индексов критичен для производительности запросов
  • Java разработчик должен понимать EXPLAIN PLAN и индексную стратегию БД
В чем разница между кластеризованными и некластеризованными индексами? | PrepBro