linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/kb/Индексы/index-design

kb/indexes ── Индексы ── intermediate

Проектирование индексов

Индекс - отсортированный список. Составной (a,b,c) работает по префиксу слева направо, не по средней колонке. Покрывающие (INCLUDE), частичные (WHERE) и по выражению сужают работу; лишние индексы - налог на запись.

view as markdownaka: composite-index, partial-index, covering-index, index-checklist

Ментальная модель: B-tree-индекс - данные, отсортированные по ключу, со ссылками на строки. Отсюда все правила.

Правило префикса

Индекс (a, b, c) сортирует по a, затем b, затем c. Помогает запросам по префиксу:

  • WHERE a = 1 - да; a = 1 AND b = 2 - да; полный ключ - да;
  • WHERE b = 2 - нет (b не в начале, записи разбросаны).

Порядок колонок: равенство раньше, диапазон/сортировку в конец.

ORDER BY без сортировки

sql
-- индекс (forked_from_id, updated_at DESC) убирает Sort:
SELECT * FROM repos WHERE forked_from_id = 42 ORDER BY updated_at DESC LIMIT 10;

Индекс отдаёт строки уже в нужном порядке - бери первые 10 и стоп.

Покрывающие, частичные, по выражению

sql
CREATE INDEX ON repos (forked_from_id, updated_at DESC) INCLUDE (name);  -- покрытие
CREATE INDEX ON tasks (created_at) WHERE status = 'active';              -- частичный
CREATE INDEX ON users (lower(email));                                    -- по выражению

Цена записи

Каждый индекс обновляется на запись; неиспользуемые - чистый убыток:

sql
SELECT indexrelname, idx_scan FROM pg_stat_user_indexes WHERE idx_scan = 0;

Слишком много индексов вредит и записи, и планированию. Индекс заводят под доказанную потребность. Условие должно быть sargable (см. sargability); тип под оператор - через operator-classes.

§ команды

bash
CREATE INDEX ON t (a, b);

Составной индекс: равенство раньше, диапазон/сортировка в конец

bash
CREATE INDEX ON t (c) WHERE status='active';

Частичный индекс - только нужные строки, меньше и дешевле

bash
SELECT indexrelname, idx_scan FROM pg_stat_user_indexes WHERE idx_scan=0;

Найти неиспользуемые индексы под удаление

§ см. также

  • sargabilitySargability: почему индекс не используетсяУсловие sargable, если индекс по колонке к нему применим. Каст или функция над колонкой (created::date, lower(email)) делают его не-sargable - индекс игнорируется, план уходит в Seq Scan. Лечение - переписать или индекс по выражению.
  • operator-classesOperator classes и выбор индексаИндекс работает не «на колонке», а для конкретных операторов над ней. Связь тип+оператор+метод доступа задаёт operator class. Через каталог pg_amop можно узнать, какой AM поддерживает оператор: @> знают gin и gist, не btree.
  • btree-internalsB-tree: split, дедупликация, INCLUDEПри переполнении страница делится (split), разделитель поднимается вверх; high key и right link дают параллельный доступ. Дедупликация хранит повтор один раз с posting list; suffix truncation обрезает разделители; INCLUDE покрывает запрос.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки