Промты для SQL-миграций: как LLM переносит схему с MySQL на PostgreSQL без потери данных

SQL на стероидах: как LLM превращает сложные запросы в понятный код

Каждый аналитик и разработчик знает: написать SQL-запрос — это полдела. Настоящая боль начинается, когда нужно разобраться в чужом EXPLAIN ANALYZE, переписать медленный JOIN или объяснить джуну, почему оконная функция с PARTITION BY работает не так, как он ожидал. LLM уже умеют генерировать SQL, но без правильного промта вы получите шаблонный ответ, который не учитывает особенности вашей схемы и версии PostgreSQL.

В этой подборке — 13 проверенных промтов для работы с реляционными базами. Они разбиты на три уровня: базовые (для повседневных задач), продвинутые (для оптимизации и сложной логики) и экспертные (для чтения планов и тонкой настройки). Каждый промт сопровождается примером запроса и пояснением, когда его применять.

Базовые промты: генерация и понимание запросов

1. Генерация сложного JOIN с пояснением

Задача: быстро собрать запрос с несколькими JOIN, не запутавшись в алиасах и условиях.

Промт:

Ты — опытный PostgreSQL-разработчик. Напиши SQL-запрос для схемы:
- users (id, name, email, created_at)
- orders (id, user_id, amount, status, created_at)
- order_items (id, order_id, product_id, quantity, price)
- products (id, name, category, price)

Нужно: вывести имя пользователя, email, общую сумму заказов за последние 30 дней и количество товаров в каждом заказе. Учти, что статус заказа может быть 'paid', 'pending', 'cancelled' — бери только 'paid'. Отсортируй по убыванию суммы. Объясни каждое соединение и условие.

Пример результата: LLM выдаст запрос с JOIN orders ON users.id = orders.user_id, LEFT JOIN order_items для подсчёта товаров и WHERE orders.created_at >= NOW() - INTERVAL '30 days' AND orders.status = 'paid'. В пояснении укажет, что LEFT JOIN нужен, чтобы не потерять заказы без товаров (хотя в реальности таких быть не должно — это повод проверить данные).

Когда применять: при написании запросов к незнакомой схеме или когда нужно быстро получить рабочий каркас.

2. Объяснение чужого запроса простым языком

Задача: разобраться, что делает запрос коллеги, который уволился полгода назад.

Промт:

Объясни, что делает этот SQL-запрос, простым языком для джуна. Разбери каждую часть: SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY. Укажи, какие данные он вернёт и какие могут быть подводные камни.

[вставьте запрос]

Пример результата: LLM разберёт запрос по строкам, укажет, что HAVING COUNT(*) > 5 фильтрует группы после агрегации, а ORDER BY без LIMIT может вернуть миллион строк. Часто такое объяснение выявляет скрытые баги — например, неявное приведение типов в WHERE.

Когда применять: при онбординге, ревью кода или рефакторинге унаследованной базы.

3. Конвертация запроса между диалектами

Задача: перенести запрос с MySQL на PostgreSQL (или наоборот) без потери логики.

Промт:

Перепиши этот MySQL-запрос для PostgreSQL. Сохрани всю логику, но используй синтаксис PostgreSQL. Обрати внимание на:
- функции работы с датами (DATE_FORMAT → TO_CHAR)
- LIMIT/OFFSET
- кавычки для идентификаторов
- обработку NULL в агрегатах

[вставьте запрос]

Пример результата: LLM заменит IFNULL на COALESCE, DATE_FORMAT(created_at, '%Y-%m') на TO_CHAR(created_at, 'YYYY-MM'), а также укажет, что в PostgreSQL GROUP BY требует явного перечисления неагрегированных колонок (если не используется функциональная зависимость от первичного ключа).

Когда применять: при миграции между СУБД или написании переносимого кода.

Что проверить первым После конвертации всегда проверяйте план выполнения — разные СУБД могут по-разному оптимизировать один и тот же запрос. Сравните EXPLAIN в исходной и целевой базе.

Продвинутые промты: оконные функции и оптимизация

4. Оконные функции для анализа данных

Задача: посчитать running total, rank и скользящее среднее без подзапросов.

Промт:

Напиши SQL-запрос с оконными функциями для таблицы sales (id, product_id, sale_date, amount). Нужно:
1. Для каждого product_id посчитать накопительную сумму продаж по дате (running total).
2. Присвоить ранг каждого product_id по общей сумме продаж (rank).
3. Вычислить скользящее среднее amount за последние 3 продажи для каждого product_id.

Используй OVER (PARTITION BY ... ORDER BY ...). Объясни разницу между ROWS и RANGE в рамке окна.

Пример результата: LLM сгенерирует запрос с SUM(amount) OVER (PARTITION BY product_id ORDER BY sale_date), RANK() OVER (ORDER BY SUM(amount) DESC) и AVG(amount) OVER (PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW). В пояснении укажет, что ROWS считает физические строки, а RANGE — логические группы (например, все продажи за один день).

Когда применять: для аналитики, отчётов и замены коррелированных подзапросов.

5. Поиск узких мест в индексах

Задача: понять, почему запрос медленный, и какие индексы добавить.

Промт:

Проанализируй этот запрос и предложи индексы для ускорения. Учти:
- какие колонки используются в WHERE, JOIN, ORDER BY
- селективность колонок
- тип индекса (B-tree, GIN, BRIN)
- порядок колонок в составном индексе

[вставьте запрос и схему таблиц]

Пример результата: LLM предложит составной индекс (status, created_at) для фильтрации по статусу и дате, объяснит, что для полнотекстового поиска нужен GIN, а для больших таблиц с диапазонными запросами — BRIN. Предупредит, что индекс по низкоселективной колонке (например, is_active) может не использоваться.

Когда применять: при тюнинге медленных запросов или проектировании схемы.

6. Переписывание запроса под большую нагрузку

Задача: убрать коррелированные подзапросы и заменить их на JOIN или оконные функции.

Промт:

Перепиши этот запрос так, чтобы он работал быстрее на большой таблице (10 млн строк). Избавься от коррелированных подзапросов, используй JOIN и оконные функции. Объясни, почему новая версия эффективнее.

[вставьте запрос]

Пример результата: LLM заменит SELECT (SELECT COUNT(*) FROM orders WHERE user_id = u.id) на LEFT JOIN (SELECT user_id, COUNT(*) FROM orders GROUP BY user_id) o ON u.id = o.user_id. В пояснении укажет, что коррелированный подзапрос выполняется для каждой строки, а GROUP BY + JOIN — один раз.

Когда применять: при оптимизации отчётов и дашбордов.

Ключевое различие Оконные функции не уменьшают количество строк, а агрегаты с GROUP BY — уменьшают. Если нужно сохранить детализацию и добавить агрегат — используйте OVER, если нужна сводка — GROUP BY.

Экспертные промты: планы и тонкая настройка

7. Чтение EXPLAIN ANALYZE

Задача: разобрать план выполнения и найти самое дорогое место.

Промт:

Прочитай вывод EXPLAIN (ANALYZE, BUFFERS) для этого запроса. Найди узкие места: seq scan на больших таблицах, неэффективные join, высокий actual time. Объясни, что означает каждый узел плана и какие действия предпринять.

[вставьте вывод EXPLAIN]

Пример результата: LLM укажет, что Seq Scan on orders (cost=0.00..12345.67 rows=100000 width=50) (actual time=0.123..456.789 rows=100000 loops=1) означает полное сканирование, и предложит индекс. Обратит внимание на Buffers: shared hit=1000 read=5000 — высокое чтение с диска сигнализирует о нехватке кэша.

Когда применять: при диагностике медленных запросов в production.

8. Сравнение планов до и после оптимизации

Задача: убедиться, что изменения действительно ускорили запрос.

Промт:

Сравни два плана EXPLAIN ANALYZE: до и после добавления индекса. Обрати внимание на:
- изменение типа сканирования (Seq Scan → Index Scan)
- actual time и rows
- стоимость (cost)
- использование памяти (Work_Mem)

Сделай вывод, помог ли индекс.

Пример результата: LLM покажет, что время выполнения упало с 456 мс до 12 мс, но предупредит, что индекс может замедлить INSERT/UPDATE. Рекомендует проверить нагрузку на запись.

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

9. Настройка autovacuum и analyze

Задача: понять, почему статистика устарела и планы стали плохими.

Промт:

Объясни, как настроить autovacuum для таблицы с интенсивными обновлениями. Какие параметры изменить (autovacuum_vacuum_scale_factor, autovacuum_analyze_scale_factor) и почему. Как проверить, что статистика актуальна?

Пример результата: LLM порекомендует уменьшить autovacuum_vacuum_scale_factor с 0.2 до 0.05 для часто обновляемых таблиц, чтобы vacuum запускался чаще. Покажет запрос к pg_stat_user_tables для проверки last_autovacuum и last_autoanalyze.

Когда применять: при деградации производительности без видимых причин.

10. Поиск блокировок и deadlock'ов

Задача: выявить, какие транзакции блокируют друг друга.

Промт:

Напиши SQL-запрос к системным представлениям PostgreSQL (pg_locks, pg_stat_activity), который покажет текущие блокировки и ожидающие транзакции. Объясни, как читать результат и находить источник deadlock'а.

Пример результата: LLM предложит запрос с JOIN между pg_locks и pg_stat_activity, который выведет pid, query, wait_event_type, wait_event. Объяснит, что wait_event_type = 'Lock' указывает на ожидание блокировки.

Когда применять: при зависаниях приложения или ошибках «deadlock detected».

Что проверить первым Перед анализом блокировок убедитесь, что у вас есть права на чтение pg_locks и pg_stat_activity. В некоторых облачных PostgreSQL эти представления могут быть ограничены.

Экспертные промты: продвинутая диагностика

11. Генерация тестовых данных для нагрузки

Задача: создать реалистичный датасет для бенчмарка.

Промт:

Сгенерируй SQL-скрипт для создания 1 млн строк в таблице orders (id, user_id, amount, status, created_at). Данные должны быть реалистичными: 80% заказов со статусом 'paid', даты за последний год, сумма от 100 до 10000. Используй generate_series.

Пример результата: LLM напишет INSERT INTO orders SELECT generate_series(1,1000000), (random()*1000)::int, (random()*9900+100)::numeric(10,2), CASE WHEN random() < 0.8 THEN 'paid' ELSE 'pending' END, NOW() - (random() * INTERVAL '365 days'). Это позволит протестировать запросы на объёме, близком к production.

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

12. Аудит безопасности запросов

Задача: проверить, нет ли SQL-инъекций и опасных конструкций.

Промт:

Проверь этот SQL-запрос на безопасность. Есть ли риск SQL-инъекции? Используются ли параметризованные запросы? Есть ли опасные операции (DROP, TRUNCATE, DELETE без WHERE)? Предложи исправления.

[вставьте запрос]

Пример результата: LLM обнаружит конкатенацию строк в WHERE id = " + userInput + " и порекомендует использовать параметризованные запросы ($1). Укажет, что DELETE FROM logs без WHERE может удалить все данные.

Когда применять: при код-ревью или перед деплоем.

13. Документирование схемы и запросов

Задача: автоматически сгенерировать комментарии к таблицам и сложным запросам.

Промт:

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

[вставьте DDL и запрос]

Пример результата: LLM сгенерирует COMMENT ON TABLE orders IS 'Заказы пользователей'; и пояснит, что order_items связана с orders по order_id. Для запроса добавит построчные комментарии, которые можно вставить в код.

Когда применять: при передаче проекта или для документации в репозитории.

Неочевидный вывод LLM часто лучше справляются с EXPLAIN ANALYZE, если вы дадите им не только план, но и схему таблиц и индексов. Без контекста они могут предложить индекс, который уже существует.

Как использовать эти промты в работе

Эти 13 промтов покрывают основные сценарии: от генерации запросов до диагностики блокировок. Начните с базовых, чтобы ускорить повседневные задачи, затем переходите к продвинутым для оптимизации. Экспертные промты требуют больше контекста, но окупаются при работе с высоконагруженными системами.

Помните: LLM — это инструмент, а не замена пониманию SQL. Всегда проверяйте сгенерированные запросы на тестовых данных и сравнивайте планы выполнения. Для углублённого изучения баз данных и смежных тем загляните в Операционные системы и системное программирование в 2026 году, где есть материалы по системному программированию и инфраструктуре.

← Все статьи

Спросить AI по этой статье

Задайте вопрос по этой статье — ASI Biont ответит, опираясь на её текст.

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

Нейрохакинг и когнитивная оптимизация: как за неделю собрать протокол, который реально работает

27 октября 2026

Цифровая гигиена за вечер: как найти утечки персональных данных и удалить информацию о себе из интернета

27 октября 2026

Налоговый вычет в 2026: как вернуть деньги за обучение, лечение и квартиру и не потерять их на документах

27 октября 2026

Full-Stack AI Engineer: как RAG-пайплайны, векторные базы данных и развертывание LLM на самом деле работают в продакшене

28 октября 2026

CIPM / CIPP/E — Управление конфиденциальностью и GDPR (IAPP): как статистика правоприменения GDPR превращает риск несоответствия требованиям в статью бюджета

28 октября 2026

Сверка актов вручную или промптом: где LLM экономит бухгалтеру часы, а где создаёт риски

12 ноября 2026

Эмоциональный интеллект: как измерить базовый уровень EQ, вести дневник эмоций и составить 30-дневный план саморегуляции

28 октября 2026

Quant Finance и Structured Products — количественные финансы: как на самом деле считают рыночный риск и где ломаются модели

29 октября 2026

Запуск бизнеса с нуля: от идеи до первых продаж — комплексная программа для старта собственного дела

29 октября 2026