diff --git a/docs/db-diagnostics.md b/docs/db-diagnostics.md new file mode 100644 index 0000000..3f1aeb9 --- /dev/null +++ b/docs/db-diagnostics.md @@ -0,0 +1,90 @@ +# Диагностика схемы PostgreSQL (EvoBGP) + +Runbook для оценки объёма БД и узких мест **перед** и **после** миграций оптимизации схемы. Выполнять на staging или production read-only сессией. + +## Подключение + +```bash +psql "$EVOBGP_DATABASE_URL" +``` + +## 1. Размеры таблиц и индексов + +```sql +SELECT relname, + pg_size_pretty(pg_total_relation_size(relid)) AS total, + pg_size_pretty(pg_relation_size(relid)) AS heap, + pg_size_pretty(pg_indexes_size(relid)) AS indexes +FROM pg_catalog.pg_statio_user_tables +ORDER BY pg_total_relation_size(relid) DESC; +``` + +**Ожидание:** лидеры — `revision_materialized_prefix`, `config_revision` (TOAST от preview), JSONB-кэши. + +## 2. Seq scan (горячие таблицы) + +```sql +SELECT schemaname, relname, seq_scan, seq_tup_read, idx_scan +FROM pg_stat_user_tables +WHERE schemaname = 'public' +ORDER BY seq_tup_read DESC; +``` + +Сброс статистики после деплоя: `SELECT pg_stat_reset();` (только осознанно, теряется baseline). + +## 3. Неиспользуемые индексы + +```sql +SELECT indexrelname, idx_scan, pg_size_pretty(pg_relation_size(indexrelid)) AS size +FROM pg_stat_user_indexes +WHERE schemaname = 'public' AND idx_scan = 0 +ORDER BY pg_relation_size(indexrelid) DESC; +``` + +## 4. Дубликаты в materialized prefixes + +Перед UNIQUE `(revision_id, prefix, community_id, source)`: + +```sql +SELECT revision_id, prefix, community_id, source, COUNT(*) AS n +FROM revision_materialized_prefix +GROUP BY 1, 2, 3, 4 +HAVING COUNT(*) > 1 +LIMIT 20; +``` + +## 5. Шаблон отчёта staging + +| Метрика | До | После | Дата | +|---------|-----|-------|------| +| `revision_materialized_prefix` total | | | | +| `config_revision` total | | | | +| `module_prefix_snapshot` total | | | | +| `asn_prefix_cache` total | | | | +| Top seq_scan table | | | | +| Unused indexes (count) | | | | + +## 6. EXPLAIN для типовых запросов + +```sql +-- Список префиксов ревизии (keyset) +EXPLAIN (ANALYZE, BUFFERS) +SELECT prefix::text, community_id::text, source +FROM revision_materialized_prefix +WHERE revision_id = ''::uuid +ORDER BY id +LIMIT 51; + +-- Diff added (anti-join) +EXPLAIN (ANALYZE, BUFFERS) +SELECT b.prefix::text +FROM revision_materialized_prefix b +LEFT JOIN revision_materialized_prefix a + ON a.revision_id = ''::uuid AND a.prefix = b.prefix +WHERE b.revision_id = ''::uuid + AND a.prefix IS NULL +ORDER BY b.prefix +LIMIT 5001; +``` + +Цель: Index Scan / Bitmap Index Scan по `(revision_id, …)`, без Seq Scan на больших таблицах.