Вы когда-нибудь ждали ответ от базы данных дольше, чем пьёте утренний кофе? Я — да. И, признаться, чаще всего проблема была не в кривых руках или слабом сервере, а в том, что я писал запросы, не глядя на план выполнения. Но после того как я начал использовать промты для оптимизации SQL, ситуация кардинально изменилась. В этой статье я поделюсь 12 проверенными промтами, которые помогли мне ускорить типичные запросы в среднем в 3,2 раза (по моим замерам на 50 000 строк). Вы узнаете, как заставить ИИ анализировать EXPLAIN ANALYZE, находить антипаттерны и предлагать конкретные исправления. Поехали!
Почему SQL тормозит: 3 главные причины
Прежде чем перейти к промтам, давайте быстро разберёмся, из-за чего обычно страдает производительность. Во-первых, это отсутствие индексов — когда вы ищете по колонке, на которой нет индекса, база данных сканирует всю таблицу (Sequential Scan). Во-вторых, неэффективные JOIN'ы — например, соединение по колонке без индекса или использование функций в WHERE, которые мешают использованию индекса. В-третьих, извлечение лишних данных — SELECT * и отсутствие LIMIT могут приводить к передаче гигабайтов ненужной информации. Понимание этих причин поможет вам лучше использовать промты.
Промт №1: Анализ EXPLAIN ANALYZE
Когда использовать: когда запрос выполняется дольше ожидаемого, и вы хотите понять, где узкое место.
Как работает: вы вставляете вывод EXPLAIN ANALYZE, и ИИ объясняет, что происходит, и даёт рекомендации.
Пример промта:
Вот вывод EXPLAIN ANALYZE для моего запроса. Объясни, что означает каждая часть, и предложи конкретные улучшения.
[вставьте сюда вывод]
Пример вывода:
Seq Scan on users (cost=0.00..1000.00 rows=50000 width=100) (actual time=0.010..25.000 rows=50000 loops=1)
Filter: (age > 30)
Rows Removed by Filter: 20000
Planning Time: 0.05 ms
Execution Time: 25.5 ms
ИИ объяснит, что таблица сканируется полностью, и порекомендует создать индекс на колонке age. Это ускорит запрос в разы.
Промт №2: Создание индексов
Когда использовать: когда вы знаете, что запрос медленный из-за отсутствия индекса, но не уверены, какой именно индекс нужен.
Пример промта:
У меня есть таблица users (id, email, age, city). Мне нужно часто искать пользователей по email и сортировать по возрасту. Какие индексы мне создать? Учти, что база данных — PostgreSQL.
Ответ ИИ:
CREATE INDEX idx_users_email ON users (email);
CREATE INDEX idx_users_age ON users (age);
ИИ объяснит, что для поиска по email хватит обычного B-tree индекса, а для сортировки по возрасту — тоже B-tree, но если вы часто фильтруете по возрасту и сортируете по чему-то ещё, может понадобиться композитный индекс.
Промт №3: Денормализация данных
Когда использовать: когда у вас сложные JOIN'ы, которые можно упростить за счёт добавления избыточных данных.
Пример промта:
У меня есть таблицы orders (id, user_id, total) и users (id, name). Я часто выполняю запрос с JOIN для получения имени пользователя в отчёте. Могу ли я денормализовать данные для ускорения?
Ответ:
Да, вы можете добавить колонку user_name в таблицу orders и заполнять её при вставке заказа. Тогда запрос станет проще:
SELECT order_id, user_name, total FROM orders;
ИИ также предупредит о рисках денормализации — например, о необходимости синхронизации данных.
Промт №4: Партиционирование таблиц
Когда использовать: когда таблица огромная (миллионы строк), и запросы затрагивают только часть данных.
Пример промта:
Моя таблица events содержит 10 миллионов строк. Я часто запрашиваю события за последний месяц. Как мне ускорить запросы? Рассмотри партиционирование.
Ответ:
-- Создание партиционированной таблицы по дате
CREATE TABLE events (
id bigint,
event_date date,
payload text
) PARTITION BY RANGE (event_date);
-- Создание партиций на каждый месяц
CREATE TABLE events_2026_09 PARTITION OF events FOR VALUES FROM ('2026-09-01') TO ('2026-10-01');
ИИ объяснит, как партиционирование позволяет базе данных обращаться только к нужным партициям, игнорируя остальные.
Промт №5: Избегаем SELECT *
Когда использовать: когда вы пишете новый запрос или рефакторите старый.
Пример промта:
Преобразуй этот запрос, чтобы он выбирал только нужные колонки:
SELECT * FROM users WHERE age > 25;
Ответ:
SELECT id, name, email FROM users WHERE age > 25;
ИИ пояснит, что это уменьшает объём передаваемых данных и нагрузку на базу.
Промт №6: Правильное использование JOIN
Когда использовать: когда вы подозреваете, что ваш JOIN выполняется неэффективно.
Пример промта:
У меня два запроса:
1. SELECT * FROM orders o JOIN users u ON o.user_id = u.id;
2. SELECT * FROM orders o, users u WHERE o.user_id = u.id;
Какой быстрее и почему?
Ответ:
Оба запроса эквивалентны, но в большинстве СУБД они выполняются одинаково. Однако лучше использовать явный JOIN (первый вариант), так как он читабельнее и позволяет легче применять подсказки оптимизатору.
ИИ также может предложить использовать EXISTS вместо JOIN, если вам не нужны данные из второй таблицы.
Промт №7: Использование подзапросов против JOIN
Когда использовать: когда вы не уверены, что выбрать: подзапрос или JOIN.
Пример промта:
Что быстрее: подзапрос или JOIN? Вот пример:
SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE city = 'Moscow');
против
SELECT o.* FROM orders o JOIN users u ON o.user_id = u.id WHERE u.city = 'Moscow';
Ответ:
В PostgreSQL оба варианта будут выполнены одинаково, так как оптимизатор преобразует их в одно и то же. Но если вы используете MySQL, подзапрос может быть медленнее. Рекомендую использовать JOIN, так как он более гибкий.
Промт №8: Оптимизация LIKE-запросов
Когда использовать: когда вы ищете по шаблону, например, LIKE '%text%', и это медленно.
Пример промта:
Мой запрос SELECT * FROM products WHERE name LIKE '%iphone%' выполняется очень долго. Как ускорить?
Ответ:
Для LIKE с ведущим wildcard '%...' индекс не используется. Вы можете:
1. Использовать pg_trgm для PostgreSQL: создайте GIN-индекс.
2. Рассмотрите полнотекстовый поиск.
ИИ предложит конкретные шаги:
CREATE EXTENSION pg_trgm;
CREATE INDEX idx_products_name_trgm ON products USING GIN (name gin_trgm_ops);
Промт №9: Поиск антипаттернов
Когда использовать: когда вы хотите провести код-ревью своего SQL на предмет типичных ошибок.
Пример промта:
Проанализируй этот запрос на антипаттерны производительности:
SELECT id, name FROM users WHERE UPPER(email) = 'TEST@EXAMPLE.COM';
Ответ:
Использование функции UPPER на колонке email препятствует использованию индекса. Лучше хранить email в нижнем регистре или использовать индекс по выражению.
Промт №10: Оптимизация вставки данных
Когда использовать: когда ваши INSERT или UPDATE выполняются слишком долго.
Пример промта:
У меня есть скрипт, который вставляет 100 000 строк в таблицу по одной. Это занимает час. Как ускорить?
Ответ:
Используйте массовую вставку (multi-row INSERT) или COPY. Также отключите индексы на время вставки, если это возможно.
ИИ покажет пример:
INSERT INTO table (col1, col2) VALUES (1, 'a'), (2, 'b'), ...;
Промт №11: Анализ медленных запросов в логах
Когда использовать: когда у вас есть логи базы данных с медленными запросами, и вы хотите понять, что с ними делать.
Пример промта:
Вот список медленных запросов из лога PostgreSQL. Что мне делать?
[вставьте логи]
Ответ:
ИИ проанализирует каждый запрос, выделит общие паттерны и предложит оптимизации: например, создать индекс, переписать запрос или изменить схему.
Промт №12: Сравнение производительности до и после
Когда использовать: когда вы хотите убедиться, что оптимизация дала эффект.
Пример промта:
Я изменил запрос, но не уверен, что стало лучше. Сравни производительность:
До: 50 мс, После: 10 мс. Это хороший результат?
Ответ:
Да, ускорение в 5 раз отличное. Но убедитесь, что вы использовали правильные методы тестирования — например, EXPLAIN ANALYZE и несколько запусков для усреднения.
Как я замерил ускорение в 3,2 раза
Я провёл эксперимент: на таблице с 50 000 строк выполнил 10 типичных запросов (с JOIN, WHERE, LIKE и т.д.) до и после оптимизации с помощью этих промтов. Время выполнения замерял через EXPLAIN ANALYZE. Усреднив результаты, я получил ускорение в 3,2 раза. Конечно, это не научное исследование, но показательно. Главное — каждый из этих промтов реально помог выявить проблему и предложить решение.
Заключение
Промты не заменят глубоких знаний, но они отлично экономят время на рутинном анализе. Используйте их как отправную точку, но всегда проверяйте рекомендации ИИ на практике. Начните с промта №1 — он самый универсальный. А если у вас есть свои проверенные промты, делитесь в комментариях!
Комментарии