revise July 2019 SQL articles
Build and deploy / deploy (push) Successful in 14s

This commit is contained in:
2026-07-31 10:37:50 +03:00
parent 368fa96733
commit bbedf1ae87
7 changed files with 766 additions and 1 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Производство редакционных партий
На 31 июля 2026 года строгий аудит проходит 49 из 358 созданных материалов. Остальные 309 не считаются «почти готовыми»: их нужно заменить, а не косметически удлинить.
На 31 июля 2026 года строгий аудит проходит 52 из 358 созданных материалов. Остальные 306 не считаются «почти готовыми»: их нужно заменить, а не косметически удлинить.
## Одна партия
+138
View File
@@ -0,0 +1,138 @@
# П17 · июль 2019 · SQL-индексы и планы PostgreSQL — тройное ревью
Статус: **принят в публикационный слой 31 июля 2026 года**. Registry
накладывает три ревизии по стабильным slug и сохраняет дату и автора базового
архива:
- <code>editorial-2019-07-practice-sql-indexes</code>;
- <code>editorial-2019-07-mechanism-sql-indexes</code>;
- <code>editorial-2019-07-field-sql-indexes</code>.
Созданы только пять файлов:
- <code>web/scripts/upgrade-2019-07.mjs</code>;
- <code>web/public/assets/editorial/2019/sql-indexes-selectivity-2019.svg</code>;
- <code>web/public/assets/editorial/2019/sql-indexes-plan-reading-2019.svg</code>;
- <code>web/public/assets/editorial/2019/sql-indexes-predicate-shape-2019.svg</code>;
- этот файл.
Модуль экспортирует ровно три revision без полей <code>date</code> и
<code>author</code>. При прямом вызове с <code>--print-revisions</code> он пишет
только JSON, совпадающий с import-safe export. SQL-фикстура находится внутри
контента как учебный, воспроизводимый сценарий; у модуля нет второго
исполняемого режима и он не меняет базу при audit.
## Проход 1. Факты и техника — пройдено
| Утверждение или решение | Первичный источник | Проверенная граница |
| --- | --- | --- |
| Планировщик выбирает план по структуре запроса и свойствам данных; при изменении селективности может выбрать другую стратегию | [PostgreSQL 11: Using EXPLAIN](https://www.postgresql.org/docs/11/using-explain.html) | Тексты не называют <code>Seq Scan</code> ошибкой. Один и тот же ключ допускает разные планы для <code>ready</code> и <code>waiting</code> |
| <code>EXPLAIN ANALYZE</code> исполняет statement и показывает фактические rows/time; rows и time на узле усреднены на один <code>loops</code> | [PostgreSQL 11: Using EXPLAIN](https://www.postgresql.org/docs/11/using-explain.html) | В статьях <code>cost</code> не превращается в миллисекунды, а маленький внутренний узел не оценивается без учёта loops |
| <code>EXPLAIN (ANALYZE, BUFFERS)</code> нужно запускать с той же осторожностью, что и исходный statement; изменяющий пример помещён в транзакцию с rollback | [PostgreSQL 11: EXPLAIN](https://www.postgresql.org/docs/11/sql-explain.html) | В материалах нет рекомендации безопасно запускать UPDATE «только ради плана» на production |
| Селективность определяется приблизительной статистикой; <code>pg_stats</code> является читаемым представлением, а <code>ANALYZE</code> обновляет статистику | [PostgreSQL 11: Statistics Used by the Planner](https://www.postgresql.org/docs/11/planner-stats.html), [PostgreSQL 11: ANALYZE](https://www.postgresql.org/docs/11/sql-analyze.html) | <code>ANALYZE</code> не обещает индексный узел: он обновляет входные данные планировщика, после чего план снимается заново |
| B-tree — кандидат для распространённых сравнений равенства и диапазона, но индекс имеет цену поддержки | [PostgreSQL 11: Index Types](https://www.postgresql.org/docs/11/indexes-types.html), [Introduction to Indexes](https://www.postgresql.org/docs/11/indexes-intro.html) | Условие «столбец проиндексирован» не выдаётся за доказательство выигрыша для массовой выборки |
| Запрос по выражению может использовать индекс на том же выражении; такой индекс вычисляется и поддерживается при записи | [PostgreSQL 11: Indexes on Expressions](https://www.postgresql.org/docs/11/indexes-expressional.html) | Предикат <code>created_at::date</code> не объявлен автоматически плохим: предложены два варианта — семантически верный range или обоснованный expression index |
| Partial index применим, когда WHERE запроса доказуемо включает его predicate; распознавание ограничено и идёт при планировании | [PostgreSQL 11: Partial Indexes](https://www.postgresql.org/docs/11/indexes-partial.html) | Prepared statement не объявлен «никогда не использующим partial index»; текст оставляет точную границу доказуемости параметризированного условия |
### Честная граница фикстуры
Фикстура создаёт изолированную схему <code>p17_sql_index_fixture</code> в
disposable-базе, миллион синтетических строк с распределением 99/1, два B-tree
индекса, <code>ANALYZE</code> и три запроса <code>EXPLAIN (ANALYZE, BUFFERS)</code>.
Она не содержит ожидаемого дерева, вычисленных миллисекунд или фиктивных
<code>actual rows</code>: это должен вывести реальный сервер с его версией,
настройками стоимости и буферами.
В среде подготовки пакета <code>psql</code> не найден и подключение к
PostgreSQL не предоставлено. Поэтому автор **не заявляет запуск базы или
измерение плана**. Это ограничение прямо написано в каждой статье и не
заменено неподтверждённым скриншотом. Перед интеграцией fixture следует
выполнить только в отдельной disposable-базе PostgreSQL 11 и сохранить:
точный SQL и параметры, версию сервера, <code>SHOW random_page_cost</code>,
<code>SHOW seq_page_cost</code>, <code>SHOW effective_cache_size</code>, plan и
контекст нагрузки.
Вердикт прохода: **пройден**. Технические утверждения привязаны к первичной
документации PostgreSQL 11; места, зависящие от конкретного контура, названы
планом проверки, а не выполненным замером.
## Проход 2. Редактура и голос М2 / 2019 — пройдено
| Ревизия | Симптом и цена в начале | Главный вопрос | Практический артефакт и ограничение |
| --- | --- | --- | --- |
| Практика | Добавили индекс, но запрос не ускорился; цена — лишняя стоимость INSERT/UPDATE без выигрыша чтения | Как различить честный Seq Scan, плохую селективность и неверную статистику | SQL-фикстура 99/1, таблица причин, <code>pg_stats</code> и маршрут EXPLAIN; нет обещания одинакового plan на каждом сервере |
| Механизм | В тикете есть скриншот с Index/Seq Scan, но нет actual rows и параметров; цена — лечить не тот узел | Как читать estimate, actual, loops, Buffers, Index Cond и Filter как единое дерево | Безопасный EXPLAIN/rollback пример, схема потока и маршрут первого расхождения; нет выдуманного production-time |
| Полевой разбор | Индекс <code>(created_at)</code> есть, а <code>created_at::date</code> всё ещё читает таблицу; цена — раздутая схема без диагноза | Как отличить selectivity, statistics и predicate shape | Инвентаризация catalog, range versus expression index и partial predicate; timezone и PREPARE оставлены явными границами |
- Первые абзацы называют «симптом», «проблему» и цену решения. Далее каждый
текст держит одну цепочку: симптом → причина → проверка → действие →
ограничение. Вместо общих оценок названы <code>rows</code>,
<code>actual rows</code>, <code>loops</code>, <code>Buffers</code>,
<code>pg_stats</code>, <code>Index Cond</code> и <code>Filter</code>.
- Голос соответствует М2 / 2019: автор уверенно работает с SQL,
PostgreSQL, серверным планом, query shape и базовой доставкой данных, но не
приписывает себе управление платформой, SLO, распределённую трассировку,
Kubernetes или продуктовые метрики поздних лет.
- Тон краткий и прагматичный. Нет абсолютов «индекс всегда ускоряет» или
«Seq Scan всегда плох». Каждый совет требует наблюдаемой проверки до DDL.
- Длина, количество разделов, таблица с <code>caption</code>/<code>thead</code>
и <code>scope</code>, код, упорядоченный маршрут, figure с alt/caption и
два или больше первичных источника дополнительно проверяются draft gate.
Вердикт прохода: **пройден**. Тексты развивают автора от практической
диагностики к более системному чтению планов, но остаются на его правдоподобной
глубине 2019 года.
## Проход 3. Визуал и выпуск — пройдено в пределах автономного пакета
- <code>sql-indexes-selectivity-2019.svg</code> сопоставляет одинаковый
индекс с двумя распределениями результата: 990 000 <code>ready</code> и
10 000 <code>waiting</code>. Нижняя карточка явно говорит сравнить rows,
actual rows, loops и Buffers, а не ждать обязательный Index Scan.
- <code>sql-indexes-plan-reading-2019.svg</code> показывает вертикальный поток
данных от scan к результату и помечает первое расхождение estimate/actual
как точку расследования. Схема не подменяет настоящий plan и не содержит
цифр, объявленных измерением.
- <code>sql-indexes-predicate-shape-2019.svg</code> отделяет индексный ключ
<code>(created_at)</code>, выражение <code>created_at::date</code> и
полуоткрытый range. Низ схемы оставляет обязательную проверку timezone и
EXPLAIN ANALYZE, чтобы скорость не сломала границу календарного дня.
- В каждом SVG есть <code>title</code>, <code>desc</code>,
<code>role="img"</code> и связка <code>aria-labelledby</code>. У картинок в
статьях есть самостоятельный содержательный alt и <code>figcaption</code>.
В SVG нет JavaScript, внешних URL или растровых вложений. Вертикальные
viewBox и короткие подписи дают масштабируемую композицию в контейнере
статьи; XML-проверка входит в выпускной набор.
- Автономный пакет не изменяет registry, поэтому не заявляет production build
или опубликованный browser-page. Реальный рендер страницы, strict audit
общего архива и build остаются задачами интегратора после подключения
revision по slug.
### Фактические проверки
```text
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 года:
| Проверка | Результат |
| --- | --- |
| <code>node --check</code> | PASS, синтаксис модуля корректен |
| <code>--print-revisions</code> | PASS, stdout — JSON, export import-safe и содержит ровно три revision |
| <code>npm run audit:draft -- scripts/upgrade-2019-07.mjs</code> | PASS: 11 230 / 10 655 / 10 608 знаков основного текста |
| <code>xmllint --noout</code> для трёх SVG | PASS, XML корректен |
| Scope/self-review | PASS: в рабочем дереве появились только пять разрешённых файлов; SVG не содержат script, внешних URL, <code>foreignObject</code> или растровых data URI |
После подключения registry основной редактор повторил strict audit: все три
slug прошли объём 11 230 / 10 655 / 10 608 знаков, figure, таблицу, код,
маршрут действий и источники. <code>npm run build</code> завершился с кодом 0
и сгенерировал 374 статические страницы.
Выпусковой вердикт: **принят к публикации**. <code>articles.json</code> не
менялся; registry заменяет только редакционные поля по стабильному slug.