15 KiB
П17 · июль 2019 · SQL-индексы и планы PostgreSQL — тройное ревью
Статус: принят в публикационный слой 31 июля 2026 года. Registry накладывает три ревизии по стабильным slug и сохраняет дату и автора базового архива:
editorial-2019-07-practice-sql-indexes;editorial-2019-07-mechanism-sql-indexes;editorial-2019-07-field-sql-indexes.
Созданы только пять файлов:
web/scripts/upgrade-2019-07.mjs;web/public/assets/editorial/2019/sql-indexes-selectivity-2019.svg;web/public/assets/editorial/2019/sql-indexes-plan-reading-2019.svg;web/public/assets/editorial/2019/sql-indexes-predicate-shape-2019.svg;- этот файл.
Модуль экспортирует ровно три revision без полей date и
author. При прямом вызове с --print-revisions он пишет
только JSON, совпадающий с import-safe export. SQL-фикстура находится внутри
контента как учебный, воспроизводимый сценарий; у модуля нет второго
исполняемого режима и он не меняет базу при audit.
Проход 1. Факты и техника — пройдено
| Утверждение или решение | Первичный источник | Проверенная граница |
|---|---|---|
| Планировщик выбирает план по структуре запроса и свойствам данных; при изменении селективности может выбрать другую стратегию | PostgreSQL 11: Using EXPLAIN | Тексты не называют Seq Scan ошибкой. Один и тот же ключ допускает разные планы для ready и waiting |
EXPLAIN ANALYZE исполняет statement и показывает фактические rows/time; rows и time на узле усреднены на один loops |
PostgreSQL 11: Using EXPLAIN | В статьях cost не превращается в миллисекунды, а маленький внутренний узел не оценивается без учёта loops |
EXPLAIN (ANALYZE, BUFFERS) нужно запускать с той же осторожностью, что и исходный statement; изменяющий пример помещён в транзакцию с rollback |
PostgreSQL 11: EXPLAIN | В материалах нет рекомендации безопасно запускать UPDATE «только ради плана» на production |
Селективность определяется приблизительной статистикой; pg_stats является читаемым представлением, а ANALYZE обновляет статистику |
PostgreSQL 11: Statistics Used by the Planner, PostgreSQL 11: ANALYZE | ANALYZE не обещает индексный узел: он обновляет входные данные планировщика, после чего план снимается заново |
| B-tree — кандидат для распространённых сравнений равенства и диапазона, но индекс имеет цену поддержки | PostgreSQL 11: Index Types, Introduction to Indexes | Условие «столбец проиндексирован» не выдаётся за доказательство выигрыша для массовой выборки |
| Запрос по выражению может использовать индекс на том же выражении; такой индекс вычисляется и поддерживается при записи | PostgreSQL 11: Indexes on Expressions | Предикат created_at::date не объявлен автоматически плохим: предложены два варианта — семантически верный range или обоснованный expression index |
| Partial index применим, когда WHERE запроса доказуемо включает его predicate; распознавание ограничено и идёт при планировании | PostgreSQL 11: Partial Indexes | Prepared statement не объявлен «никогда не использующим partial index»; текст оставляет точную границу доказуемости параметризированного условия |
Честная граница фикстуры
Фикстура создаёт изолированную схему p17_sql_index_fixture в
disposable-базе, миллион синтетических строк с распределением 99/1, два B-tree
индекса, ANALYZE и три запроса EXPLAIN (ANALYZE, BUFFERS).
Она не содержит ожидаемого дерева, вычисленных миллисекунд или фиктивных
actual rows: это должен вывести реальный сервер с его версией,
настройками стоимости и буферами.
В среде подготовки пакета psql не найден и подключение к
PostgreSQL не предоставлено. Поэтому автор не заявляет запуск базы или
измерение плана. Это ограничение прямо написано в каждой статье и не
заменено неподтверждённым скриншотом. Перед интеграцией fixture следует
выполнить только в отдельной disposable-базе PostgreSQL 11 и сохранить:
точный SQL и параметры, версию сервера, SHOW random_page_cost,
SHOW seq_page_cost, SHOW effective_cache_size, plan и
контекст нагрузки.
Вердикт прохода: пройден. Технические утверждения привязаны к первичной документации PostgreSQL 11; места, зависящие от конкретного контура, названы планом проверки, а не выполненным замером.
Проход 2. Редактура и голос М2 / 2019 — пройдено
| Ревизия | Симптом и цена в начале | Главный вопрос | Практический артефакт и ограничение |
|---|---|---|---|
| Практика | Добавили индекс, но запрос не ускорился; цена — лишняя стоимость INSERT/UPDATE без выигрыша чтения | Как различить честный Seq Scan, плохую селективность и неверную статистику | SQL-фикстура 99/1, таблица причин, pg_stats и маршрут EXPLAIN; нет обещания одинакового plan на каждом сервере |
| Механизм | В тикете есть скриншот с Index/Seq Scan, но нет actual rows и параметров; цена — лечить не тот узел | Как читать estimate, actual, loops, Buffers, Index Cond и Filter как единое дерево | Безопасный EXPLAIN/rollback пример, схема потока и маршрут первого расхождения; нет выдуманного production-time |
| Полевой разбор | Индекс (created_at) есть, а created_at::date всё ещё читает таблицу; цена — раздутая схема без диагноза |
Как отличить selectivity, statistics и predicate shape | Инвентаризация catalog, range versus expression index и partial predicate; timezone и PREPARE оставлены явными границами |
- Первые абзацы называют «симптом», «проблему» и цену решения. Далее каждый
текст держит одну цепочку: симптом → причина → проверка → действие →
ограничение. Вместо общих оценок названы
rows,actual rows,loops,Buffers,pg_stats,Index CondиFilter. - Голос соответствует М2 / 2019: автор уверенно работает с SQL, PostgreSQL, серверным планом, query shape и базовой доставкой данных, но не приписывает себе управление платформой, SLO, распределённую трассировку, Kubernetes или продуктовые метрики поздних лет.
- Тон краткий и прагматичный. Нет абсолютов «индекс всегда ускоряет» или «Seq Scan всегда плох». Каждый совет требует наблюдаемой проверки до DDL.
- Длина, количество разделов, таблица с
caption/theadиscope, код, упорядоченный маршрут, figure с alt/caption и два или больше первичных источника дополнительно проверяются draft gate.
Вердикт прохода: пройден. Тексты развивают автора от практической диагностики к более системному чтению планов, но остаются на его правдоподобной глубине 2019 года.
Проход 3. Визуал и выпуск — пройдено в пределах автономного пакета
sql-indexes-selectivity-2019.svgсопоставляет одинаковый индекс с двумя распределениями результата: 990 000readyи 10 000waiting. Нижняя карточка явно говорит сравнить rows, actual rows, loops и Buffers, а не ждать обязательный Index Scan.sql-indexes-plan-reading-2019.svgпоказывает вертикальный поток данных от scan к результату и помечает первое расхождение estimate/actual как точку расследования. Схема не подменяет настоящий plan и не содержит цифр, объявленных измерением.sql-indexes-predicate-shape-2019.svgотделяет индексный ключ(created_at), выражениеcreated_at::dateи полуоткрытый range. Низ схемы оставляет обязательную проверку timezone и EXPLAIN ANALYZE, чтобы скорость не сломала границу календарного дня.- В каждом SVG есть
title,desc,role="img"и связкаaria-labelledby. У картинок в статьях есть самостоятельный содержательный alt иfigcaption. В SVG нет JavaScript, внешних URL или растровых вложений. Вертикальные viewBox и короткие подписи дают масштабируемую композицию в контейнере статьи; XML-проверка входит в выпускной набор. - Автономный пакет не изменяет registry, поэтому не заявляет production build или опубликованный browser-page. Реальный рендер страницы, strict audit общего архива и build остаются задачами интегратора после подключения revision по slug.
Фактические проверки
node --check web/scripts/upgrade-2019-07.mjs
cd web && npm run audit:draft -- scripts/upgrade-2019-07.mjs
xmllint --noout \
web/public/assets/editorial/2019/sql-indexes-selectivity-2019.svg \
web/public/assets/editorial/2019/sql-indexes-plan-reading-2019.svg \
web/public/assets/editorial/2019/sql-indexes-predicate-shape-2019.svg
Результат финального запуска 31 июля 2026 года:
| Проверка | Результат |
|---|---|
node --check |
PASS, синтаксис модуля корректен |
--print-revisions |
PASS, stdout — JSON, export import-safe и содержит ровно три revision |
npm run audit:draft -- scripts/upgrade-2019-07.mjs |
PASS: 11 230 / 10 655 / 10 608 знаков основного текста |
xmllint --noout для трёх SVG |
PASS, XML корректен |
| Scope/self-review | PASS: в рабочем дереве появились только пять разрешённых файлов; SVG не содержат script, внешних URL, foreignObject или растровых data URI |
После подключения registry основной редактор повторил strict audit: все три
slug прошли объём 11 230 / 10 655 / 10 608 знаков, figure, таблицу, код,
маршрут действий и источники. npm run build завершился с кодом 0
и сгенерировал 374 статические страницы.
Выпусковой вердикт: принят к публикации. articles.json не
менялся; registry заменяет только редакционные поля по стабильному slug.