Почему промты для SQL — это не хайп, а необходимость
Каждый день разработчики тратят часы на анализ планов запросов, поиск недостающих индексов и написание миграций. По данным опроса Stack Overflow Developer Survey 2025, более 60% респондентов работают с базами данных ежедневно, и почти половина из них называют оптимизацию запросов самой времязатратной задачей. Нейросети уже умеют генерировать SQL, но без точных формулировок результат часто бесполезен. В этой подборке — 12 проверенных промтов, которые я использую в своей практике для PostgreSQL, MySQL и других СУБД. Они покрывают всё: от диагностики блокировок до онлайн-миграций без простоя.
1. Анализ медленного запроса через EXPLAIN (ANALYZE, BUFFERS)
Задача: понять, почему запрос выполняется 5 секунд вместо 50 мс.
Промт:
Ты — эксперт по PostgreSQL. Проанализируй вывод EXPLAIN (ANALYZE, BUFFERS) для запроса ниже. Найди узкие места: последовательные сканирования, неверные оценки кардинальности, дорогие сортировки. Предложи конкретные шаги: какие индексы создать, как переписать запрос. Запрос: [вставь SQL]. План: [вставь вывод EXPLAIN].
Пример: запрос SELECT * FROM orders WHERE user_id = 123 AND created_at > '2026-01-01' выполнялся 4.2 с. После промта нейросеть указала на Seq Scan по таблице orders (2 млн строк) и предложила составной индекс (user_id, created_at). После создания индекса время упало до 12 мс.
2. Генерация индексов под конкретные запросы
Задача: создать оптимальные индексы, не замедляющие вставку.
Промт:
Ты — DBA. Есть таблица [имя] с полями [перечисли]. Частые запросы: [список]. Предложи 3 варианта индексов с оценкой влияния на SELECT и INSERT. Учти порядок колонок, включение (INCLUDE), частичные индексы. Дай DDL для каждого варианта.
Пример: для таблицы payments с запросами по status и created_at нейросеть предложила частичный индекс CREATE INDEX idx_payments_pending ON payments (created_at) WHERE status = 'pending';. Это ускорило выборку в 8 раз и почти не повлияло на вставку.
3. Переписывание запроса с подзапросами в JOIN
Задача: убрать коррелированные подзапросы, которые выполняются для каждой строки.
Промт:
Перепиши запрос, заменив коррелированные подзапросы на JOIN или оконные функции. Сохрани семантику. Объясни, почему новая версия быстрее. Исходный запрос: [SQL].
Пример: запрос с WHERE EXISTS (SELECT 1 FROM ...) для 100k строк выполнялся 12 с. После переписывания на JOIN — 0.8 с.
4. Диагностика блокировок и взаимоблокировок (deadlocks)
Задача: найти, кто держит блокировку и почему возникают deadlock.
Промт:
Ты — эксперт по PostgreSQL. Проанализируй вывод pg_locks и pg_stat_activity. Найди транзакции, которые блокируют другие, и предложи порядок действий для устранения. Если есть deadlock — объясни причину и как переписать код. Данные: [вставь вывод запросов].
Пример: после промта удалось выявить, что транзакция UPDATE accounts держала блокировку 30 секунд из-за отсутствия индекса на внешнем ключе. Создание индекса устранило проблему.
5. Оптимизация пагинации (OFFSET vs Keyset)
Задача: ускорить листание больших таблиц.
Промт:
Сравни два подхода к пагинации: OFFSET/LIMIT и Keyset (WHERE id > last_id ORDER BY id LIMIT N). Для таблицы [имя] с 10 млн строк покажи, какой запрос будет быстрее и почему. Напиши оба варианта SQL.
Пример: для таблицы logs пагинация через OFFSET 1000000 занимала 2.3 с, а Keyset — 15 мс.
6. Миграция схемы без блокировки таблицы (PostgreSQL)
Задача: добавить колонку или изменить тип без простоя.
Промт:
Ты — эксперт по миграциям PostgreSQL. Предложи безопасный способ добавить колонку [имя] типа [тип] в таблицу [имя] с 50 млн строк без блокировки. Используй ALTER TABLE ... ADD COLUMN с DEFAULT NULL, затем батчевое заполнение. Учти блокировки. Дай пошаговый план и SQL.
Пример: добавление колонки status через ALTER TABLE users ADD COLUMN status text DEFAULT 'active'; в PostgreSQL 11+ не требует перезаписи таблицы, но для старых версий нужен обходной путь. Промт сгенерировал план из 5 шагов.
7. Создание индекса CONCURRENTLY
Задача: создать индекс на продакшене без остановки записи.
Промт:
Напиши команду CREATE INDEX CONCURRENTLY для таблицы [имя] по колонкам [список]. Объясни, чем отличается от обычного CREATE INDEX, какие ограничения (нельзя в транзакции, может упасть). Дай команду для отката.
Пример: CREATE INDEX CONCURRENTLY idx_users_email ON users (email); — выполняется дольше, но не блокирует запись.
8. Поиск неиспользуемых индексов
Задача: избавиться от лишних индексов, замедляющих вставку.
Промт:
Проанализируй статистику pg_stat_user_indexes. Найди индексы, которые не использовались ни разу с момента сброса статистики. Предложи их удалить. Учти, что некоторые индексы нужны для уникальности или внешних ключей. Данные: [вывод запроса].
Пример: из 20 индексов на таблице products 7 не использовались. Удаление ускорило INSERT на 15%.
9. Оптимизация JOIN-ов с большими таблицами
Задача: ускорить соединение двух и более таблиц.
Промт:
Есть запрос с JOIN между [таблицы]. Он выполняется медленно. Предложи: 1) изменить порядок JOIN, 2) использовать CTE или временные таблицы, 3) добавить индексы. Объясни, какой план лучше. Исходный SQL: [SQL].
Пример: запрос с JOIN orders ON users.id = orders.user_id и фильтром по orders.created_at выиграл от индекса на orders(user_id, created_at) и изменения порядка соединения.
10. Написание сложного запроса с оконными функциями
Задача: посчитать ранги, скользящие средние, нарастающие итоги.
Промт:
Напиши SQL-запрос для PostgreSQL, который вычисляет [бизнес-задача]. Используй оконные функции: ROW_NUMBER, RANK, SUM() OVER, AVG() OVER. Поясни каждую часть. Таблицы: [описание].
Пример: для расчёта кумулятивной выручки по дням: SUM(amount) OVER (ORDER BY date) AS cumulative_revenue.
11. Миграция данных между таблицами батчами
Задача: перенести миллионы строк без нагрузки на репликацию.
Промт:
Напиши скрипт на Python (psycopg2) или SQL для батчевого переноса данных из [таблица1] в [таблица2] порциями по 10 000 строк с паузами. Учти, чтобы не блокировать таблицу и не перегружать WAL. Дай код и пояснения.
Пример: скрипт с LIMIT 10000 OFFSET ... и time.sleep(0.1) между батчами.
12. Автоматическая генерация миграций для ORM
Задача: создать файл миграции для Django, Alembic или Prisma.
Промт:
Ты — эксперт по [Django/Alembic/Prisma]. Сгенерируй миграцию для изменения: [описание]. Учти зависимости, обратимость, возможные блокировки. Предложи SQL для ручной проверки.
Пример: для Django-миграции добавления поля slug в модель Post с null=True.
Что дальше?
Эти промты — не догма, а отправная точка. Адаптируйте их под свою СУБД, версию PostgreSQL и конкретные таблицы. Всегда проверяйте сгенерированный SQL на тестовой среде. Помните: нейросеть ускоряет рутину, но ответственность за продакшен лежит на вас.
Попробуйте применить хотя бы три промта из подборки в ближайшую неделю — и увидите, как время на оптимизацию сократится в разы. А если у вас есть свои любимые формулировки, делитесь в комментариях.
Источники:
- Официальная документация PostgreSQL: https://www.postgresql.org/docs/current/performance-tips.html
- Stack Overflow Developer Survey 2025: https://survey.stackoverflow.co/2025/
- Use The Index, Luke! — https://use-the-index-luke.com/
Комментарии