12 промтов, которые превращают LLM в дежурного DBA: PostgreSQL, MongoDB и Redis под нагрузкой
Половина дежурств в бэкенд-командах выглядит одинаково: приходит алерт о росте латентности, ты открываешь pg_stat_statements, потом EXPLAIN ANALYZE на запрос, который кто-то написал два года назад, потом ищешь, почему Mongo не использует индекс, а Redis внезапно съел всю память. LLM не заменяет DBA, но отлично работает как второй пилот: расшифровывает планы запросов, находит N+1, предлагает индексы и схемы шардирования — если правильно сформулировать задачу.
Ниже — 12 промтов, которые я собрал по реальным разборам. Каждый — с примером входных данных (план запроса, схема, лог) и с тем, что делать с ответом модели, чтобы не просто «получить текст», а применить в проде. Важно: любые рекомендации по индексам, миграциям и шардированию всегда проверяйте на staging-реплике, а не сразу на проде.
1. Расшифровка EXPLAIN (ANALYZE, BUFFERS) человеческим языком
Задача: план запроса выглядит как иероглифы, непонятно, где реальное узкое место.
Промт:
Ты — эксперт по PostgreSQL 16. Ниже EXPLAIN (ANALYZE, BUFFERS) запроса.
Разбери план по узлам: где реальное время (actual time), где оценка
rows сильно расходится с реальностью (rows vs actual rows), какие узлы
дают Seq Scan / Nested Loop с большим числом итераций.
Выведи таблицу: узел
| что делает | actual time | rows est vs actual | подозрение.
Затем дай 3 гипотезы причины и что проверить (индексы, статистика, настройки).
Не предлагай переписывать запрос, пока не объяснишь план.
План:
<вставь сюда вывод EXPLAIN>
Пример входа: план с Seq Scan on orders (cost=0..124000 rows=1 width=...) и actual rows=48213.
Что делать с ответом: расхождение оценок в разы — почти всегда сигнал обновить статистику (ANALYZE orders;) или поднять default_statistics_target для проблемной колонки. Проверяйте гипотезы через EXPLAIN (ANALYZE, BUFFERS) повторно.
2. Поиск N+1 в коде и логах ORM
Задача: API отвечает медленно, в логах — сотни похожих SELECT-ов.
Промт:
Ниже фрагмент лога SQL-запросов от ORM (по одной строке на запрос).
Найди паттерн N+1: одинаковые запросы с разными значениями в WHERE,
идущие подряд. Для каждого паттерна укажи: сущность, число вызовов,
какой JOIN или eager-load (select_related / joinedload / include)
его устранит. Покажи пример кода до и после на Python/SQLAlchemy
(или укажи, если ORM другая).
Лог:
<вставь строки лога>
Что делать с ответом: сравните число запросов до и после в staging. По документации SQLAlchemy selectinload против joinedload ведут себя по-разному на больших выборках — проверьте оба варианта.
3. Генерация индекса под конкретный запрос
Задача: нужен индекс, но не хочется плодить лишние (они замедляют запись).
Промт:
Ты — DBA PostgreSQL. Вот схема таблицы (DDL) и медленный запрос.
Предложи индексы: тип (btree/hash/gin/gist/brin), колонки, порядок,
частичный индекс (WHERE), include-колонки для index-only scan.
Для каждого индекса объясни, какой узел плана он ускорит и какую
цену на запись добавит. Отдельно скажи, если индекс не нужен.
DDL:
<вставь CREATE TABLE + индексы>
Запрос:
<вставь SQL>
Что делать с ответом: проверьте через EXPLAIN (ANALYZE) до и после, а стоимость записи — через pg_stat_user_indexes и pg_stat_user_tables (колонка n_tup_ins/upd/del).
4. Рефакторинг медленного JOIN
Задача: JOIN на 3–4 таблицы деградировал после роста данных.
Промт:
Перепиши запрос так, чтобы уменьшить объём промежуточных строк:
варианты — переставить порядок JOIN, вынести фильтр в подзапрос,
использовать EXISTS вместо JOIN, применить lateral join.
Для каждого варианта покажи SQL и объясни, почему он может быть
быстрее. Не меняй семантику результата. Укажи, где нужен индекс.
Запрос:
<SQL>
Схемы и примерные размеры таблиц:
<таблицы и row count>
Что делать с ответом: сравнивайте варианты по EXPLAIN (ANALYZE, BUFFERS) и по реальному времени на реплике. Семантику проверяйте тестами — LLM иногда меняет LEFT JOIN на INNER.
5. Аудит блокировок и поиск дедлоков
Задача: приложение падает с deadlock detected.
Промт:
Ниже лог PostgreSQL с сообщением о дедлоке (DEADLOCK DETECTED)
и списком процессов. Определи, какие транзакции конкурируют,
на каких строках/таблицах, в каком порядке берутся блокировки.
Предложи: порядок блокировок, который снимет дедлок, и где в коде
добавить SELECT ... FOR UPDATE SKIP LOCKED или advisory lock.
Лог:
<вставь лог>
Что делать с ответом: проверьте pg_locks и pg_stat_activity в момент инцидента. Универсальное правило: захватывайте блокировки в одном и том же порядке во всех транзакциях.
6. Промт для MongoDB: почему запрос не использует индекс
Задача: find сканирует коллекцию, хотя индекс есть.
Промт:
Ты — эксперт по MongoDB 7. Ниже вывод explain("executionStats")
и определение индексов коллекции. Объясни, почему выбран COLLSCAN
вместо IXSCAN. Проверь: порядок полей в составном индексе,
ESR-правило (Equality, Sort, Range), типы значений, использование
операторов, которые мешают индексу. Предложи конкретный индекс
и порядок полей. Покажи команду createIndex.
Explain:
<вставь JSON explain>
Индексы:
<db.collection.getIndexes()>
Что делать с ответом: применяйте createIndex в фоне (background: true в старых версиях; в 4.2+ все индексы строятся гибридно), проверяйте winningPlan повторно.
7. Схема шардирования в MongoDB
Задача: коллекция растёт, один репликасет не тянет.
Промт:
Предложи стратегию шардирования коллекции MongoDB.
Дано: схема документов, паттерны запросов (какие поля в фильтрах,
какие в сортировках), оценка роста. Оцени варианты shard key:
hashed vs ranged, кардинальность, риск hot shard, поддержка
целевых запросов без scatter-gather. Укажи, какие индексы
нужны до шардирования и как переносить данные.
Схема и запросы:
<документ, фильтры, сортировки>
Что делать с ответом: помните, что shard key нельзя изменить без пересоздания коллекции. Проверяйте распределение через sh.status() и db.collection.getShardDistribution().
8. Стратегия кэширования в Redis
Задача: решить, что и как кэшировать, чтобы не получить stale data.
Промт:
Ты — эксперт по Redis 7. Предложи стратегию кэширования для
следующих данных: <опиши сущности и частоту чтения/записи>.
Для каждой сущности укажи: структуру (String/Hash/Sorted Set),
TTL, политику инвалидации (write-through, write-behind, cache-aside),
риск stale data и как его снизить (версионирование ключей,
pub/sub инвалидация). Предупреди про перегрев на массовом
истечении TTL и предложи jitter.
Данные и нагрузка:
<описание>
Что делать с ответом: TTL ставьте с джиттером, иначе получите лавину промахов в одну секунду. Для инвалидации через pub/sub помните: сообщения не гарантируют доставку при разрыве соединения.
9. Подбор eviction policy и диагностика OOM в Redis
Задача: Redis падает с OOM command not allowed.
Промт:
Ниже вывод INFO memory и INFO stats из Redis, а также maxmemory
и maxmemory-policy. Объясни, почему происходит OOM: фрагментация,
большие ключи, отсутствие TTL, неверная политика.
Предложи: подходящую maxmemory-policy, что проверить через
MEMORY USAGE и --bigkeys, как найти ключи без TTL.
INFO:
<вставь вывод>
Что делать с ответом: для кэша обычно allkeys-lru или allkeys-lfu, для очередей — noeviction с алертами. Большие ключи ищите через redis-cli --bigkeys и MEMORY USAGE <key>.
10. Безопасная миграция без простоя (PostgreSQL)
Задача: добавить колонку/индекс на таблицу в сотни миллионов строк.
Промт:
Составь план миграции PostgreSQL без блокировки таблицы.
Задача: <что меняем — колонка, индекс, тип>.
Разбей на шаги с командами и таймингами: CREATE INDEX CONCURRENTLY,
ALTER TABLE ... ADD COLUMN с DEFAULT (в PG 11+ без перезаписи),
backfill батчами, добавление NOT NULL через NOT VALID + VALIDATE
CONSTRAINT. Для каждого шага укажи, блокирует ли он запись/чтение
и как откатить.
Контекст:
<таблица, размер, нагрузка>
Что делать с ответом: CREATE INDEX CONCURRENTLY нельзя запускать внутри транзакции. Проверяйте блокировки через pg_stat_activity и lock_timeout.
11. Разбор инцидента по логам и метрикам
Задача: утром пришёл алерт, непонятно, что случилось ночью.
Промт:
Ты — on-call инженер. Ниже таймлайн: метрики (QPS, latency p99,
connections, cache hit ratio) и фрагменты логов за инцидент.
Восстанови хронологию: что произошло первым, что было следствием.
Отдели симптом от причины. Предложи 3 проверяемые гипотезы
и конкретные запросы/команды для проверки (pg_stat_statements,
redis-cli INFO, db.currentOp()).
Метрики и логи:
<вставь>
Что делать с ответом: гипотезы проверяйте по порядку, фиксируйте в постмортеме. LLM хорошо связывает события, но не знает вашей инфраструктуры — добавляйте контекст.
12. Генерация тестовых данных и нагрузочного сценария
Задача: нужно проверить индекс или шардирование на реалистичных данных.
Промт:
Сгенерируй SQL для наполнения таблиц тестовыми данными:
<схема> — N строк, реалистичное распределение (например,
80% заказов у 20% пользователей, даты за последний год,
несколько NULL). Затем предложи сценарий нагрузки (pgbench
или скрипт) для проверки конкретного запроса.
Схема и цель теста:
<DDL и что проверяем>
Что делать с ответом: неоднородное распределение важнее объёма — именно оно выявляет hot shard и плохие планы. Запускайте на копии прода, а не на пустой базе.
Что важно помнить
LLM ускоряет разбор, но не отменяет проверку. Три правила: любое изменение индексов и схемы — сначала на реплике или staging; любые цифры из ответа модели считайте гипотезой, а не фактом; контекст (версия СУБД, размеры таблиц, паттерны запросов) добавляйте в промт — без него советы будут общими. Официальные источники, на которые стоит опираться при проверке: документация PostgreSQL (postgresql.org/docs), MongoDB Manual (mongodb.com/docs) и Redis Docs (redis.io/docs).
Возьмите один промт из списка и прогоните на своём самом медленном запросе прямо сегодня — часто уже первый разбор EXPLAIN экономит часы дежурства.
Комментарии