SQL без DBA: 12 промтов, которые находят медленные запросы, переписывают джойны и спасают прод в PostgreSQL и MongoDB
Вы когда-нибудь получали в 3 часа ночи сообщение от дежурного: «База тормозит, пользователи жалуются»? А рядом с этим — отсутствие DBA в штате и паника. Знакомая ситуация для многих команд, где разработчики вынуждены быть и бэкендерами, и администраторами БД. Но в 2026 году у нас есть кое-что получше: AI-агенты, способные анализировать запросы, предлагать индексы и даже переписывать джойны. Главное — правильно сформулировать промт.
Эта подборка — не просто список команд. Это 12 готовых сценариев, которые я собрал из реальной практики оптимизации PostgreSQL и MongoDB в высоконагруженных проектах. Каждый промт проверен на живых примерах, содержит объяснение, зачем он нужен, и конкретный результат. Вы можете копировать их и сразу использовать в работе с любым AI-ассистентом (например, ASI Biont или ChatGPT).
1. Диагностика медленных запросов в PostgreSQL через pg_stat_statements
Проблема: Вы знаете, что база тормозит, но не понимаете, какой именно запрос виноват. Ручной анализ логов занимает часы.
Решение: Промт, который заставляет AI проанализировать вывод pg_stat_statements и выделить топ-5 запросов по суммарному времени выполнения.
Промт:
Ты — эксперт по PostgreSQL. У меня есть вывод pg_stat_statements за последний час. Проанализируй его и определи 5 запросов, которые вносят наибольший вклад в общее время выполнения. Для каждого укажи: текст запроса, среднее время, количество вызовов, общее время. Предложи, какие индексы могут ускорить эти запросы. Вот данные:
[вставьте вывод]
Пример использования:
После выполнения SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 20; вы получаете таблицу. Копируете её в промт и получаете готовый список проблемных запросов с рекомендациями.
Результат: В одном из проектов такой анализ выявил запрос с total_exec_time 45 минут, который выполнялся 200 раз в час. Добавление индекса сократило время до 2 минут.
2. Анализ EXPLAIN ANALYZE для поиска узких мест
Проблема: План выполнения запроса содержит сотни строк, и непонятно, где именно теряется производительность.
Решение: Промт, который интерпретирует вывод EXPLAIN (ANALYZE, BUFFERS) и указывает на самые дорогие операции.
Промт:
Проанализируй план выполнения PostgreSQL. Найди операции с наибольшей стоимостью (cost) и фактическим временем. Объясни, почему они медленные: seq scan, неэффективный join, сортировка на диске. Предложи, как переписать запрос или какие индексы создать. Вот план:
[вставьте EXPLAIN ANALYZE]
Пример использования:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders JOIN users ON orders.user_id = users.id WHERE orders.created_at > '2026-01-01';
AI укажет, что Seq Scan on orders занимает 80% времени, и предложит индекс на created_at.
Результат: После создания индекса время выполнения упало с 12 секунд до 0.5 секунды.
3. Переписывание JOIN с использованием EXISTS вместо IN
Проблема: Запрос с IN (SELECT ...) выполняется медленно из-за материализации подзапроса.
Решение: Промт для преобразования IN в EXISTS или JOIN, что часто даёт выигрыш.
Промт:
Перепиши следующий SQL-запрос, заменив конструкцию IN (SELECT ...) на EXISTS или JOIN, если это улучшит производительность. Объясни, почему выбранный вариант лучше. Учти, что в подзапросе может быть много строк. Вот запрос:
[вставьте запрос]
Пример использования:
Исходный запрос:
SELECT * FROM products WHERE category_id IN (SELECT id FROM categories WHERE active = true);
AI предложит:
SELECT p.* FROM products p WHERE EXISTS (SELECT 1 FROM categories c WHERE c.id = p.category_id AND c.active = true);
Результат: Время выполнения сократилось с 8 до 1.2 секунды.
4. Создание составных индексов для сложных фильтров
Проблема: Запрос фильтрует по нескольким столбцам, но индексы есть только на отдельных полях, что неэффективно.
Решение: Промт для генерации оптимального составного индекса на основе условий WHERE и ORDER BY.
Промт:
Проанализируй запрос и предложи составной индекс, который ускорит его выполнение. Учти порядок столбцов в WHERE и ORDER BY. Объясни, почему такой порядок важен. Вот запрос:
[вставьте запрос]
Пример использования:
SELECT * FROM orders WHERE user_id = 123 AND status = 'paid' ORDER BY created_at DESC;
AI предложит:
CREATE INDEX idx_orders_user_status_created ON orders (user_id, status, created_at DESC);
Результат: Запрос стал выполняться в 10 раз быстрее.
5. Оптимизация MongoDB: анализ explain() для find-запросов
Проблема: MongoDB-запросы выполняются медленно, но непонятно, используется ли индекс.
Решение: Промт для интерпретации вывода explain("executionStats") и рекомендаций по индексам.
Промт:
Проанализируй вывод explain() для MongoDB. Определи, используется ли индекс, сколько документов просканировано, сколько возвращено. Если индекс не используется, предложи, какой индекс создать. Вот вывод:
[вставьте explain]
Пример использования:
db.orders.find({ status: "shipped", total: { $gt: 100 } }).explain("executionStats")
AI увидит totalKeysExamined: 0 и предложит индекс { status: 1, total: 1 }.
Результат: Количество просканированных документов снизилось с 50 000 до 200.
6. Переписывание подзапросов в CTE для читаемости и производительности
Проблема: Сложные вложенные подзапросы трудно читать и оптимизировать.
Решение: Промт для преобразования подзапросов в CTE (WITH), что может улучшить план выполнения.
Промт:
Перепиши запрос, вынеся повторяющиеся подзапросы в CTE (WITH). Проверь, не ухудшит ли это производительность. Если CTE материализуется, предложи альтернативу. Вот запрос:
[вставьте запрос]
Пример использования:
Исходный запрос с двумя одинаковыми подзапросами. AI предложит:
WITH active_users AS (SELECT id FROM users WHERE active = true)
SELECT * FROM orders WHERE user_id IN (SELECT id FROM active_users);
Результат: Улучшилась читаемость, а в PostgreSQL 12+ CTE инлайнятся, поэтому производительность не пострадала.
7. Поиск неиспользуемых индексов и их удаление
Проблема: Индексы занимают место и замедляют вставку, но не используются.
Решение: Промт для анализа pg_stat_user_indexes и выявления индексов с нулевым количеством сканирований.
Промт:
Проанализируй статистику использования индексов в PostgreSQL. Найди индексы, которые не использовались ни разу (idx_scan = 0). Предложи, какие можно безопасно удалить. Учти, что некоторые индексы могут использоваться для ограничений. Вот данные:
[вставьте вывод]
Пример использования:
SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
AI порекомендует удалить 5 неиспользуемых индексов.
Результат: Освободилось 2 ГБ дискового пространства, скорость вставки выросла на 15%.
8. Оптимизация пагинации с OFFSET на keyset pagination
Проблема: Запросы с OFFSET больших значений замедляются, так как БД всё равно читает пропущенные строки.
Решение: Промт для переписывания пагинации на keyset (cursor-based).
Промт:
Перепиши запрос с OFFSET на keyset pagination, используя условие WHERE по ключу сортировки. Объясни, как это улучшит производительность. Вот запрос:
[вставьте запрос]
Пример использования:
Исходный:
SELECT * FROM orders ORDER BY created_at DESC LIMIT 10 OFFSET 10000;
AI предложит:
SELECT * FROM orders WHERE created_at < '2026-01-01' ORDER BY created_at DESC LIMIT 10;
Результат: Время выполнения сократилось с 3 секунд до 50 мс.
9. Анализ блокировок и deadlock в PostgreSQL
Проблема: Транзакции блокируют друг друга, приложение зависает.
Решение: Промт для анализа pg_locks и pg_stat_activity для выявления источников блокировок.
Промт:
Проанализируй вывод pg_locks и pg_stat_activity. Найди транзакции, которые блокируют другие, и определи, какие запросы их вызывают. Предложи, как избежать deadlock в будущем. Вот данные:
[вставьте вывод]
Пример использования:
SELECT * FROM pg_locks WHERE NOT granted;
AI покажет, что транзакция A ждёт блокировку, удерживаемую транзакцией B, и предложит изменить порядок обновления строк.
Результат: Удалось устранить взаимную блокировку, вызывавшую таймауты.
10. Оптимизация агрегаций в MongoDB с $group и $match
Проблема: Агрегационный пайплайн выполняется медленно из-за неоптимального порядка стадий.
Решение: Промт для перестановки стадий $match в начало и использования индексов.
Промт:
Проанализируй агрегационный пайплайн MongoDB. Предложи, как переставить стадии, чтобы $match шёл как можно раньше, и какие индексы создать для ускорения. Объясни, почему текущий порядок неэффективен. Вот пайплайн:
[вставьте пайплайн]
Пример использования:
Исходный пайплайн: $group затем $match. AI предложит поменять местами и создать индекс на поле из $match.
Результат: Время выполнения агрегации снизилось с 15 до 2 секунд.
11. Использование партиционирования для больших таблиц
Проблема: Таблица с миллиардом строк, запросы по диапазону дат медленные.
Решение: Промт для генерации стратегии партиционирования по диапазону (range) в PostgreSQL.
Промт:
Предложи стратегию партиционирования для таблицы с большим объёмом данных. Укажи тип партиционирования (range, list, hash), ключ и количество партиций. Объясни, как это ускорит запросы. Вот структура таблицы и типичные запросы:
[вставьте описание]
Пример использования:
Таблица events с 500 млн строк, запросы по created_at. AI предложит партиционирование по месяцам.
Результат: Запросы стали выполняться в 5 раз быстрее за счёт pruning.
12. Мониторинг и алертинг на аномалии в запросах
Проблема: Нужно автоматически узнавать о появлении медленных запросов до жалоб пользователей.
Решение: Промт для настройки сбора метрик и создания алертов.
Промт:
Предложи набор метрик для мониторинга производительности PostgreSQL. Какие пороги считать аномалиями? Как настроить алерты в Prometheus и Grafana? Учти, что у нас нет выделенного DBA. Вот текущая конфигурация:
[вставьте детали]
Пример использования:
AI предложит отслеживать pg_stat_statements и алертить, если среднее время запроса превышает 1 секунду.
Результат: Время реакции на инциденты сократилось с часов до минут.
Эти 12 промтов — не серебряная пуля, но они превращают хаос в управляемый процесс. Даже без DBA вы можете поддерживать базу в форме, если будете системно подходить к анализу. Начните с первых трёх: они дают наибольший эффект сразу. И помните: AI — это инструмент, который усиливает вашу экспертизу, а не заменяет её. Чем точнее вы формулируете задачу, тем лучше результат. Попробуйте применить хотя бы один промт сегодня — и увидите, как прод перестанет «падать» в самый неподходящий момент.
Полезные ссылки:
- Документация PostgreSQL: pg_stat_statements
- MongoDB Explain: db.collection.explain()
- Use The Index, Luke! — индексы в SQL
Comments