Если вы хоть раз писали SELECT с шестью JOIN и молились, чтобы индексы сработали, — эта статья для вас. Генерация SQL с помощью ИИ перестала быть игрушкой: современные модели умеют не только строить сложные запросы, но и объяснять, почему один план выполнения лучше другого. Я собрал 15 проверенных промтов, которые реально ускоряют работу с PostgreSQL, MySQL и оптимизацией запросов. Никакой воды — только конкретика, примеры и пояснения, когда что применять.
Почему ИИ для SQL — это не замена, а усилитель
Прежде чем перейти к промтам, давайте честно: ИИ не заменит опытного DBA. Но он отлично справляется с рутиной: написать шаблонный запрос, вспомнить синтаксис оконной функции или найти узкое место в EXPLAIN. По данным опроса Stack Overflow за 2025 год, 76% разработчиков используют ИИ-ассистентов (источник: Stack Overflow Developer Survey 2025). При этом базы данных остаются одной из самых частых тем запросов. Значит, спрос есть — и сейчас мы разберем, как выжать из ИИ максимум.
Как правильно формулировать промты для SQL
Хороший промт — это половина успеха. Вот три правила, которые я вывел за годы практики:
- Контекст решает всё. Укажите версию СУБД, структуру таблиц и конкретную задачу. Промт «напиши запрос» без контекста даст общий ответ, который придется переписывать.
- Просите объяснения. Не просто «дай код», а «объясни, почему выбран этот подход». Так вы учитесь и проверяете логику.
- Используйте итерации. Первый ответ редко бывает идеальным. Уточняйте, просите альтернативы, сравнивайте.
15 промтов для PostgreSQL, MySQL и оптимизации
Базовые промты для повседневной работы
1. Написание сложного JOIN-запроса
Промт: «У меня есть таблицы customers (id, name, email), orders (id, customer_id, amount, created_at) и order_items (id, order_id, product_name, quantity, price) в PostgreSQL 16. Напиши запрос, который выводит имя клиента, сумму его заказа и количество товаров, но только для заказов за последние 30 дней. Отсортируй по сумме убыванию.»
Пример ответа:
SELECT
c.name,
o.amount AS order_amount,
COALESCE(SUM(oi.quantity), 0) AS items_count
FROM customers c
JOIN orders o ON c.id = o.customer_id
LEFT JOIN order_items oi ON o.id = oi.order_id
WHERE o.created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY c.name, o.id, o.amount
ORDER BY o.amount DESC;
Когда применять: когда нужно быстро собрать данные из нескольких связанных таблиц, не тратя время на синтаксис JOIN.
2. Использование оконных функций для ранжирования
Промт: «В таблице sales (id, region, manager, amount, sale_date) в MySQL 8.0 нужно получить топ-3 менеджера по сумме продаж в каждом регионе за 2025 год. Используй оконную функцию ROW_NUMBER().»
Пример ответа:
SELECT region, manager, total_amount
FROM (
SELECT
region,
manager,
SUM(amount) AS total_amount,
ROW_NUMBER() OVER (PARTITION BY region ORDER BY SUM(amount) DESC) AS rn
FROM sales
WHERE YEAR(sale_date) = 2025
GROUP BY region, manager
) AS ranked
WHERE rn <= 3
ORDER BY region, rn;
Когда применять: для аналитических отчетов «лучшие/худшие» по группам.
3. Генерация тестовых данных
Промт: «Сгенерируй SQL-скрипт для PostgreSQL, который создаст 1000 тестовых записей в таблице users (id serial, email varchar, created_at timestamp). Email должен быть уникальным и вида user_N@example.com, created_at — случайная дата за последний год.»
Пример ответа:
INSERT INTO users (email, created_at)
SELECT
'user_'
|| g || '@example.com',
NOW() - (random() * INTERVAL '365 days')
FROM generate_series(1, 1000) AS g;
Когда применять: для нагрузочного тестирования или разработки без реальных данных.
Продвинутые промты для сложных задач
4. Оптимизация медленного запроса
Промт: «Вот запрос на PostgreSQL 15. Он работает 15 секунд на таблице из 5 млн строк. Проанализируй и предложи оптимизации: индексы, переписывание, изменение схемы. Запрос: SELECT * FROM orders WHERE customer_id = 123 AND order_date BETWEEN '2025-01-01' AND '2025-12-31' ORDER BY order_date DESC LIMIT 10;»
Пример ответа:
-- Рекомендации:
-- 1. Создать составной индекс (customer_id, order_date DESC)
CREATE INDEX idx_orders_customer_date ON orders (customer_id, order_date DESC);
-- 2. Переписать запрос с использованием индекса:
SELECT * FROM orders
WHERE customer_id = 123
AND order_date >= '2025-01-01'
AND order_date < '2026-01-01'
ORDER BY order_date DESC
LIMIT 10;
Когда применять: когда EXPLAIN показывает seq scan, а хочется index scan.
5. Диагностика с помощью EXPLAIN
Промт: «Объясни, что означает этот план выполнения PostgreSQL: "Seq Scan on orders (cost=0.00..100000.00 rows=5000000 width=200) (actual time=0.015..1500.0 rows=5000000 loops=1)". Какие проблемы видишь и как исправить?»
Пример ответа:
Этот план показывает последовательное сканирование всей таблицы (Seq Scan) — значит, не используется индекс. Стоимость высокая (cost=100000), фактическое время 1.5 секунды. Проблема: отсутствует подходящий индекс для фильтрации. Рекомендация: создать индекс на столбцы, используемые в WHERE.
Когда применять: когда нужно быстро разобраться в плане выполнения.
6. Проектирование схемы базы данных
Промт: «Спроектируй схему для системы управления задачами в PostgreSQL. Нужны таблицы для пользователей, проектов, задач и комментариев. Учти связи many-to-many и внешние ключи. Добавь индексы для частых запросов.»
Пример ответа:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE projects (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
owner_id INT REFERENCES users(id)
);
CREATE TABLE project_members (
project_id INT REFERENCES projects(id),
user_id INT REFERENCES users(id),
PRIMARY KEY (project_id, user_id)
);
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
project_id INT REFERENCES projects(id),
title VARCHAR(255) NOT NULL,
status VARCHAR(50) DEFAULT 'todo',
assignee_id INT REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
task_id INT REFERENCES tasks(id),
user_id INT REFERENCES users(id),
content TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_tasks_project_status ON tasks (project_id, status);
CREATE INDEX idx_comments_task ON comments (task_id);
Когда применять: для быстрого прототипирования схемы.
7. Исправление ошибок в существующем запросе
Промт: «Вот запрос на MySQL, он выдает ошибку "Unknown column 'total' in field list". Найди и исправь: SELECT id, SUM(amount) AS total FROM orders GROUP BY id HAVING total > 100;»
Пример ответа:
В MySQL нельзя использовать алиас в HAVING для агрегатной функции. Правильно:
SELECT id, SUM(amount) AS total
FROM orders
GROUP BY id
HAVING SUM(amount) > 100;
Когда применять: когда ошибка неочевидна, а дедлайн горит.
Экспертные промты для профи
8. Анализ производительности с помощью EXPLAIN ANALYZE
Промт: «Выполни EXPLAIN ANALYZE для этого запроса PostgreSQL и дай рекомендации по улучшению. Запрос: SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.country = 'US' AND o.total > 1000;»
Пример ответа:
EXPLAIN ANALYZE
SELECT * FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.country = 'US' AND o.total > 1000;
Результат покажет фактическое время и стоимость. ИИ проанализирует: если видит Hash Join — предложит увеличить work_mem; если Seq Scan на customers — создать индекс на country.
Когда применять: когда нужен глубокий анализ производительности.
9. Написание сложного запроса с подзапросами и CTE
Промт: «Напиши запрос PostgreSQL, который выводит для каждого региона топ-3 товара по выручке за последний квартал. Используй CTE и оконные функции. Таблицы: sales (id, product_id, region, amount, sale_date), products (id, name).»
Пример ответа:
WITH quarterly_sales AS (
SELECT
region,
product_id,
SUM(amount) AS revenue
FROM sales
WHERE sale_date >= DATE_TRUNC('quarter', CURRENT_DATE) - INTERVAL '3 months'
GROUP BY region, product_id
),
ranked AS (
SELECT
region,
product_id,
revenue,
ROW_NUMBER() OVER (PARTITION BY region ORDER BY revenue DESC) AS rn
FROM quarterly_sales
)
SELECT r.region, p.name AS product, r.revenue
FROM ranked r
JOIN products p ON r.product_id = p.id
WHERE r.rn <= 3
ORDER BY r.region, r.revenue DESC;
Когда применять: для сложной аналитики.
10. Перевод SQL между диалектами
Промт: «Переведи этот запрос с PostgreSQL на MySQL, учитывая различия в синтаксисе: SELECT DATE_TRUNC('month', created_at) AS month, COUNT(*) FROM orders GROUP BY month;»
Пример ответа:
SELECT DATE_FORMAT(created_at, '%Y-%m-01') AS month, COUNT(*)
FROM orders
GROUP BY month;
Когда применять: при миграции БД.
11. Генерация запроса для обновления данных с условием
Промт: «В таблице products (id, price, discount) в MySQL нужно увеличить цену на 10% для товаров, где discount = 0, но не более чем до 1000. Напиши UPDATE с CASE.»
Пример ответа:
UPDATE products
SET price = CASE
WHEN price * 1.1 > 1000 THEN 1000
ELSE price * 1.1
END
WHERE discount = 0;
Когда применять: для массовых обновлений с бизнес-логикой.
12. Создание представления (VIEW) для отчетности
Промт: «Создай представление в PostgreSQL, которое показывает ежемесячную выручку по продуктам за текущий год. Включи название продукта, месяц, сумму.»
Пример ответа:
CREATE VIEW monthly_revenue AS
SELECT
p.name AS product_name,
DATE_TRUNC('month', s.sale_date) AS month,
SUM(s.amount) AS total_revenue
FROM sales s
JOIN products p ON s.product_id = p.id
WHERE s.sale_date >= DATE_TRUNC('year', CURRENT_DATE)
GROUP BY p.name, DATE_TRUNC('month', s.sale_date);
Когда применять: для упрощения отчетности.
13. Написание хранимой процедуры
Промт: «Напиши хранимую процедуру в PostgreSQL (PL/pgSQL), которая принимает customer_id и возвращает сумму всех его заказов. Используй RETURN QUERY.»
Пример ответа:
CREATE OR REPLACE FUNCTION get_customer_total(cust_id INT)
RETURNS TABLE (customer_id INT, total_amount NUMERIC) AS $$
BEGIN
RETURN QUERY
SELECT c.id AS customer_id, COALESCE(SUM(o.amount), 0) AS total_amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE c.id = cust_id
GROUP BY c.id;
END;
$$ LANGUAGE plpgsql;
Когда применять: для инкапсуляции бизнес-логики в БД.
14. Оптимизация схемы для больших данных
Промт: «У нас таблица events в PostgreSQL, 100 млн строк. Мы часто фильтруем по user_id и event_time. Предложи стратегию партиционирования и индексов.»
Пример ответа:
-- Партиционирование по диапазону дат
CREATE TABLE events (
id BIGSERIAL,
user_id INT,
event_time TIMESTAMP,
event_type VARCHAR(50),
PRIMARY KEY (id, event_time)
) PARTITION BY RANGE (event_time);
-- Создание партиций по месяцам
CREATE TABLE events_2026_01 PARTITION OF events FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
-- ... и так далее
-- Индекс на user_id и event_time
CREATE INDEX idx_events_user_time ON events (user_id, event_time);
Когда применять: для высоконагруженных систем.
15. Объяснение разницы между типами JOIN
Промт: «Объясни разницу между INNER, LEFT, RIGHT и FULL JOIN в PostgreSQL. Приведи примеры, когда какой использовать.»
Пример ответа:
- INNER JOIN: возвращает только совпадающие строки из обеих таблиц.
- LEFT JOIN: все строки из левой таблицы + совпадающие из правой.
- RIGHT JOIN: все строки из правой + совпадающие из левой.
- FULL JOIN: все строки из обеих таблиц, с NULL для отсутствующих.
Пример: для списка клиентов с заказами используйте LEFT JOIN, чтобы показать клиентов без заказов.
Когда применять: для обучения или быстрого освежения знаний.
Как проверить ответ ИИ
ИИ может ошибаться. Всегда проверяйте сгенерированный SQL на тестовой БД. Используйте EXPLAIN, чтобы убедиться, что запрос эффективен. И не забывайте: ИИ — это инструмент, а не истина в последней инстанции.
Итоги
Эти 15 промтов покрывают 80% типичных задач разработчика и аналитика: от простых JOIN до проектирования схем. Главное — давать ИИ достаточно контекста и проверять результат. Начните с пары промтов из списка, адаптируйте их под свои таблицы, и вы заметите, как сократилось время на написание SQL. А если у вас есть свои любимые промты — делитесь в комментариях, давайте соберем коллекцию!
Статья основана на личном опыте автора и официальной документации PostgreSQL и MySQL. Актуальность — август 2026 года.
Комментарии