В реляционной СУБД кортежи таблицы хранятся в неупорядоченном пространстве дисковых страниц (Heap / Куча):
TID (Block, Offset).При росте объема таблицы до миллионов строк поиск превращается в катастрофу:
O(N) операций дискового чтения.Индекс — это отдельная от таблицы физическая структура данных на диске, которая содержит отсортированные ключи и прямые указатели на строки в куче.
O(N) до O(log N).Индекс в базе данных аналогичен предметному указателю в конце 1500-страничной энциклопедии:
B-Tree (Balanced Tree) — основной тип индекса в реляционных базах данных благодаря трем физическим свойствам:
Благодаря связности листьев B-Tree выполняет запросы диапазона за минимальное время:
ORDER BY выполняется бесплатно (без фазы оперативной сортировки).TID.Для таблицы из 20 000 000 записей:
CREATE UNIQUE INDEX idx_u ON T (code);
PRIMARY KEY и ограничений UNIQUE.CREATE INDEX idx_nu ON T (fk_id);
Индекс CREATE INDEX idx_abc ON T (A, B, C); физически упорядочивает записи как в энциклопедическом словаре:
A.A — по B.A и B — по C.СУБД может использовать B-Tree индекс только начиная с самого левого столбца:
WHERE A = 1 AND B = 2 — работает эффективно!WHERE A = 1 — работает эффективно!WHERE B = 2 AND C = 3 — НЕ работает! Ведущий столбец A отсутствует, поэтому СУБД выберет Seq Scan.Определяет, какую долю строк отсекает условие фильтрации:
В составном индексе столбцы должны располагаться строго в следующем порядке:
Создание индекса — это не бесплатное ускорение, а строгий архитектурный компромисс:
«Раз я объявил FOREIGN KEY, база данных сама всё оптимизирует!» — НЕТ, ЭТО ОШИБКА!
PRIMARY KEY.DELETE FROM clients) СУБД без индекса на FK блокирует всю дочернюю таблицу целиком для проверки ссылок.Когда в таблице из 10 000 000 строк активными являются лишь 1% записей, индексировать всю таблицу — преступление.
CREATE INDEX idx_active_orders ON orders (client_id, created_at) WHERE status = 'ACTIVE';
WHERE.Seq Scan — последовательное чтение всей таблицы от начала до конца.Index Scan — прямой поиск по B-Tree с последующим точечным извлечением строк из кучи.Index Only Scan — идеальный случай (покрывающий индекс): все запрошенные поля есть в индексе, куча не читается вообще!Bitmap Index Scan — сбор битовой карты страниц по индексу при выборке сотен строк.cost=0.00..45210.00 — ожидаемые затраты СУБД (startup cost .. total cost).actual time=0.021..0.045 — реальное время выполнения при EXPLAIN ANALYZE.Rows Removed by Filter: 1999980 — катастрофа: прочитаны миллионы строк ради единиц!FOREIGN KEY отдельным индексом.[Равенства] -> [Диапазоны] -> [ORDER BY].EXPLAIN ANALYZE.Robert'); DROP TABLE Students;--.