Как я убил 40-секундные SQL-запросы на маркетплейсе: 14 промтов для PostgreSQL, которые реально работают

Проблема: отчётность, которая не успевала за бизнесом

Год назад я работал аналитиком в компании, которая владела маркетплейсом с оборотом в несколько миллионов долларов в месяц. Каждый понедельник руководство ждало отчёт по продажам за прошлую неделю. И каждый понедельник я чувствовал себя виноватым: дашборд грузился 40–50 секунд, а иногда и вовсе падал с таймаутом. Вишенкой на торте был запрос, который строил воронку продаж: он выполнялся 42 секунды, съедал 100% CPU и блокировал другие отчёты.

В какой-то момент терпение лопнуло. Я решил разобраться, почему так происходит, и использовать AI-ассистента не для написания кода с нуля, а для диагностики и оптимизации. За две недели я сократил время выполнения ключевых запросов с 40+ секунд до 200–500 миллисекунд. Ниже — 14 промтов, которые я использовал. Каждый из них проверен на реальных данных, с реальными индексами и EXPLAIN ANALYZE. Это не теория — это мой рабочий дневник.

1. «Объясни план выполнения, как будто я джун»

Зачем: EXPLAIN ANALYZE выдаёт десятки строк, в которых легко утонуть. Промт заставляет AI перевести план на человеческий язык и указать на самое узкое место.

Промт:

Ты — эксперт по PostgreSQL. Вот вывод EXPLAIN (ANALYZE, BUFFERS) для запроса:

[вставь план]

Объясни простыми словами:
1. Какие операции самые дорогие и почему?
2. Есть ли Seq Scan по большим таблицам?
3. Какие индексы могли бы помочь?
4. Что именно занимает больше всего времени?

Не предлагай переписать запрос, только диагностика.

Реальный пример: Я получил план, где был Seq Scan on orders (cost=0.00..123456.78 rows=1000000 width=120). AI объяснил: «PostgreSQL читает всю таблицу orders, потому что нет индекса по полю created_at, которое используется в WHERE. Это 1 млн строк, отсюда 40 секунд». После создания индекса время упало до 1.2 секунды.

2. «Найди неявные приведения типов»

Зачем: Неявные касты — частая причина, почему индекс не используется. Например, WHERE user_id = '123' (строка вместо числа) или WHERE created_at::date = '2026-09-01'.

Промт:

Проанализируй SQL-запрос на предмет неявных приведений типов, которые мешают использованию индексов. Покажи проблемные места и предложи, как переписать условие, чтобы индекс работал.

Запрос:
[вставь SQL]

Пример: В запросе было WHERE status = 'active' (status — enum), но PostgreSQL всё равно делал Seq Scan. AI подсказал: «Приведение к enum происходит неявно, но если в таблице 90% строк имеют status='active', планировщик может решить, что Seq Scan дешевле. Попробуй частичный индекс: CREATE INDEX idx_orders_active ON orders (created_at) WHERE status = 'active';». Помогло — запрос ускорился в 8 раз.

3. «Сгенерируй индексы под конкретный запрос»

Зачем: Иногда неочевидно, какой именно индекс нужен: составной, частичный или с включением колонок (INCLUDE).

Промт:

У меня есть запрос, который выполняется медленно. Проанализируй его и предложи 2-3 варианта индексов (составной, частичный, с INCLUDE). Для каждого варианта напиши DDL и объясни, в каких случаях он будет эффективен.

Запрос:
[вставь SQL]

Пример: Запрос фильтровал по user_id и сортировал по created_at DESC. AI предложил:

CREATE INDEX idx_orders_user_created ON orders (user_id, created_at DESC);

Время выполнения упало с 12 секунд до 80 мс.

4. «Перепиши коррелированный подзапрос в JOIN»

Зачем: Коррелированные подзапросы в SELECT или WHERE часто выполняются для каждой строки. JOIN обычно быстрее.

Промт:

Перепиши этот запрос, заменив коррелированные подзапросы на JOIN или оконные функции. Сохрани логику. Сравни производительность.

Запрос:
[вставь SQL]

Пример: Было:

SELECT o.id, (SELECT SUM(amount) FROM payments p WHERE p.order_id = o.id) AS total
FROM orders o WHERE o.created_at > '2026-09-01';

Стало:

SELECT o.id, COALESCE(SUM(p.amount), 0) AS total
FROM orders o
LEFT JOIN payments p ON p.order_id = o.id
WHERE o.created_at > '2026-09-01'
GROUP BY o.id;

Ускорение в 6 раз.

5. «Проверь, не делает ли ORM N+1 запросов»

Зачем: Если вы используете ORM (например, SQLAlchemy или Django ORM), AI может проанализировать код и найти проблему N+1.

Промт:

Вот фрагмент кода на Python (SQLAlchemy). Проверь, нет ли проблемы N+1 запросов. Если есть — покажи, как переписать с помощью joinedload или selectinload.

Код:
[вставь код]

Пример: AI нашёл, что в цикле для каждого заказа делается отдельный запрос к таблице users. После замены на joinedload(Order.user) количество запросов сократилось с 1000+ до 1, время ответа API — с 4 секунд до 200 мс.

6. «Настрой autovacuum для горячей таблицы»

Зачем: Если таблица часто обновляется, autovacuum может не успевать, и производительность падает.

Промт:

У меня есть таблица orders, в которую идёт интенсивная запись (10k строк в минуту) и обновление статусов. Предложи параметры autovacuum для этой таблицы, чтобы избежать bloat и не тормозить запросы. Объясни каждый параметр.

Пример: AI рекомендовал:

ALTER TABLE orders SET (autovacuum_vacuum_scale_factor = 0.01, autovacuum_vacuum_threshold = 1000);

После этого bloat снизился, запросы стабилизировались.

7. «Покажи, как использовать pg_stat_statements»

Зачем: Этот модуль — золотая жила для поиска медленных запросов.

Промт:

Объясни, как установить и использовать pg_stat_statements для поиска топ-10 самых ресурсоёмких запросов. Напиши SQL-запрос, который выведет запросы с самым высоким total_exec_time.

Пример: AI дал запрос:

SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Я нашёл запрос, который выполнялся 5000 раз в день и суммарно съедал 2 часа CPU. После оптимизации сэкономил кучу ресурсов.

8. «Перепиши запрос с CTE на временную таблицу»

Зачем: В PostgreSQL CTE (WITH) до версии 12 был optimisation fence. В новых версиях это исправлено, но иногда материализация всё равно мешает.

Промт:

У меня есть запрос с несколькими CTE, который выполняется медленно. Предложи переписать его с использованием временных таблиц или подзапросов. Сравни планы выполнения.

Запрос:
[вставь SQL]

Пример: Запрос с 4 CTE выполнялся 18 секунд. После переписывания на временные таблицы с индексами — 1.5 секунды.

9. «Как разбить большой запрос на части»

Зачем: Если запрос слишком сложный, его можно разбить на несколько материализованных представлений или использовать incremental approach.

Промт:

Этот запрос агрегирует данные за месяц по 10 млн строк. Предложи стратегию разбиения: материализованное представление, партиционирование или pre-aggregation. Опиши плюсы и минусы.

Пример: AI предложил создать материализованное представление, обновляемое ночью. Утром отчёты грузились мгновенно.

10. «Найди блокировки и долгие транзакции»

Зачем: Иногда запрос тормозит не из-за плана, а из-за блокировок.

Промт:

Напиши SQL-запрос к pg_locks и pg_stat_activity, который покажет все текущие блокировки и транзакции, которые их держат. Добавь фильтр по длительности > 5 секунд.

Пример: AI дал запрос, который выявил транзакцию, висящую 10 минут и блокирующую обновление статусов заказов. После kill проблема ушла.

11. «Оптимизируй сортировку и лимиты»

Зачем: ORDER BY с LIMIT может быть медленным, если нет подходящего индекса.

Промт:

Запрос: SELECT * FROM orders ORDER BY created_at DESC LIMIT 100. Предложи индекс, который ускорит эту операцию. Учти, что нужны только последние 100 записей.

Пример: AI предложил:

CREATE INDEX idx_orders_created_desc ON orders (created_at DESC);

Время выборки упало с 3 секунд до 5 мс.

12. «Проверь статистику и обнови её»

Зачем: Планировщик использует статистику. Если она устарела, план может быть неоптимальным.

Промт:

Как часто нужно запускать ANALYZE для таблицы orders? Напиши команду для ручного обновления статистики и объясни, как проверить, когда последний раз обновлялась статистика.

Пример: AI подсказал:

ANALYZE orders;
SELECT last_analyze FROM pg_stat_user_tables WHERE relname = 'orders';

После обновления статистики планировщик выбрал Index Scan вместо Seq Scan.

13. «Сгенерируй тестовые данные для нагрузочного тестирования»

Зачем: Чтобы проверить оптимизацию, нужны реалистичные данные.

Промт:

Напиши скрипт на Python, который сгенерирует 1 млн строк в таблицу orders с полями: id, user_id, amount, status, created_at. Данные должны быть реалистичными: 80% заказов оплачены, 10% отменены, 10% в обработке. created_at — случайные даты за последний год.

Пример: AI сгенерировал скрипт с использованием Faker и psycopg2. Я загрузил данные и протестировал индексы.

14. «Напиши объяснение для руководства»

Зачем: Когда вы оптимизировали запрос, нужно объяснить бизнесу, что изменилось и почему это важно.

Промт:

Напиши краткое объяснение для руководства: как оптимизация SQL-запросов повлияла на скорость отчётов и какие выгоды это принесло. Используй метафоры, избегай технического жаргона.

Пример: AI написал: «Раньше отчёт готовился 40 секунд, теперь — 0.3 секунды. Это как пересесть с лошади на болид Формулы-1. Теперь мы можем строить отчёты в реальном времени и быстрее реагировать на изменения рынка».

Результат

За две недели я оптимизировал 14 запросов. Среднее время выполнения упало с 40 секунд до 300 миллисекунд. Дашборд перестал падать, а руководство начало получать отчёты вовремя. Самое главное — я научился системно подходить к оптимизации: сначала EXPLAIN ANALYZE, потом индексы, потом переписывание запросов. AI-ассистент стал не заменой, а ускорителем: он объяснял планы, предлагал варианты и помогал не упустить детали.

Если вы работаете с PostgreSQL и сталкиваетесь с медленными запросами, начните с промта №1. Дальше — по ситуации. Главное — не бойтесь экспериментировать и всегда проверяйте результат на реальных данных. Удачи!


Источники:
- Официальная документация PostgreSQL: EXPLAIN, Indexes, pg_stat_statements.
- Статья «Understanding EXPLAIN ANALYZE» на PostgreSQL Wiki: https://wiki.postgresql.org/wiki/Using_EXPLAIN
- Книга «PostgreSQL 14 Administration Cookbook» (Simon Riggs, Gianni Ciolli).

← Все статьи

Комментарии

Читайте также

Нейросети для начинающих: как выбрать между ChatGPT, Claude и Gemini и не потерять деньги и время. Обзор курса asibiont.com

24 сентября 2026

DevOps и облака: освойте контейнерные среды и облачную карьеру в 2026 году (Docker против Podman, Kubernetes, CI/CD)

24 сентября 2026

Готовые AI-промты для мультиканального маркетинга: собери лендинг, email-серию и контент под 10 площадок

24 сентября 2026

Международные санкции и комплаенс (OFAC, ООН, ЕС, FATF): обзор курса и почему ИИ-обучение меняет правила игры

24 сентября 2026

Создание RAG-систем: Освойте генерацию с дополненной выборкой, гибридный поиск и переранжирование

24 сентября 2026

Курс эмоционального интеллекта: освойте EQ для лидеров, самосознания и управления конфликтами

24 сентября 2026

PostgreSQL под нагрузкой: промты, которые превращают EXPLAIN в план действий

24 сентября 2026

Водный и Лесной кодексы: как бизнесу легально использовать водные объекты и арендовать лес

24 сентября 2026

Как я перестал писать код вручную: 10 промтов, которые превращают сырые данные в продакшн-модель

24 сентября 2026