awesome-everything EN
↑ Обратно к восхождению

Базы данных

Индексы: спроектировать и проаудитить реальный набор индексов

Суть Практический проект — спроектировать, развернуть и проаудитить набор индексов для реалистичной multi-tenant таблицы, доказывая каждый выбор числами EXPLAIN (ANALYZE, BUFFERS) до/после.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 240 min

Читать про leading-column rule — не то же самое, что смотреть, как 4-секундный запрос дашборда падает до субмиллисекунды, потому что ты правильно собрал composite, partial-предикат и список INCLUDE. Построй реалистичную multi-tenant схему, загрузи её до масштаба и преврати каждое решение по индексу в измеренное до/после — со EXPLAIN как свидетелем на каждом шаге.

Цель

Преврати ментальную модель юнита в воспроизводимый инженерный цикл: загрузи таблицу до production-реалистичного масштаба, профилируй горячие запросы, спроектируй продуманный набор индексов (composite + partial + INCLUDE + правильные типы), разверни без блокировок, докажи каждый запрос через EXPLAIN, затем прогони playbook аудита и верни то, что тратится зря.

Проект
0 из 7
Цель

Возьми multi-tenant схему tasks/comments (стартер ниже или свою), загрузи до ~50-100M строк с реалистичным перекосом по status и спроектируй, разверни и проаудитируй полный набор индексов так, чтобы каждый горячий запрос выполнялся как Index Only Scan или селективный Index Scan — каждый доказан числами EXPLAIN (ANALYZE, BUFFERS) до/после, при суммарном хранилище индексов под ~20% от размера таблицы.

Требования
Критерии приёмки
  • Таблица до/после на каждый горячий запрос: тип скана (Seq Scan -> Index Only / Index Scan), Heap Fetches, Buffers и общее время выполнения — измеренные на полном масштабе, не на глаз.
  • Каждый задуманный index-only scan показывает Heap Fetches: 0 после VACUUM, и ни один запрос, который должен обслуживаться индексом, не показывает Seq Scan или узел Sort после скана.
  • Демонстрация каскада удаления родителя показывает, как многосекундный/минутный Seq-Scan каскад схлопывается до быстрого index lookup, как только FK-колонка comments проиндексирована.
  • Суммарное хранилище индексов под ~20% от размера таблицы, с одним абзацем бюджетного учёта (размер каждого индекса, зачем он, какой запрос обслуживает) и leading-column обоснованием каждого composite.
  • Сводка аудита с именами каждого найденного неиспользуемого/избыточного/раздутого индекса и освобождённым местом, плюс подтверждение, что ни один горячий запрос не деградировал после дропов.
Senior-стретч
  • Добавь pg_trgm fuzzy-поиск (ILIKE-anywhere / similarity по title) и pgvector HNSW семантический поиск по колонке embedding; сравни размер индекса, write-стоимость и recall с базой GIN tsvector.
  • Продемонстрируй ловушку неявного приведения end-to-end: покажи WHERE bigint_col = '42' (TEXT-литерал) с seq-scan, затем версию с типизированным параметром, использующую индекс — сними оба плана.
  • Поставь эксперимент с HOT-обновлениями: снизь fillfactor до 70 на update-тяжёлой таблице, гони обновления, не меняющие ни одной индексируемой колонки, и покажи падение index writes (HOT n_tup_hot_upd в pg_stat_user_tables) против fillfactor 100.
  • Добавь CI-гейт: запускай EXPLAIN (ANALYZE) на пяти горячих запросах против засеянного canary на каждой миграции и роняй сборку, если любой план регрессирует к Seq Scan, узлу Sort или Heap Fetches выше порога.
Итог

Это цикл, который ты будешь прогонять в любой реальной задаче индексирования: загрузи до реалистичного масштаба, сними базу горячих запросов через EXPLAIN (ANALYZE, BUFFERS), спроектируй продуманный набор (composite вокруг всегда присутствующего фильтра, partial для горячего подмножества, INCLUDE для проекции, правильный тип под форму данных), разверни CONCURRENTLY и проверь indisvalid, проиндексируй каждую FK-колонку, докажи, что каждый запрос обслуживается индексом с Heap Fetches: 0, затем проаудитируй неиспользуемые/избыточные/раздутые индексы и верни потери. Один раз на реалистичной схеме — и production-версия становится мышечной памятью.

Продолжить восхождение ↑EXPLAIN и планы выполнения: что решает планировщик и почему
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.