12 промтов для ускорения PostgreSQL: разбор EXPLAIN, индексы и партиционирование без простоя

Почему ваши SQL-запросы тормозят, а промты для AI — ускоряют

PostgreSQL — мощная СУБД, но даже опытные разработчики часто теряются, когда запрос выполняется минутами. Чтение планов EXPLAIN, выбор индексов, партиционирование — всё это требует глубоких знаний. По данным Stack Overflow Developer Survey 2025, PostgreSQL остаётся самой популярной базой данных (46% респондентов), но лишь 12% разработчиков считают себя экспертами в оптимизации. AI-ассистенты могут сократить разрыв: они генерируют гипотезы, предлагают индексы и переписывают запросы. В этой подборке — 12 промтов, которые я собрал из практики работы с высоконагруженными системами. Каждый промт сопровождается примером запроса, ожидаемым результатом и пояснением. Вы можете сразу применить их в своём проекте.

1. Расшифровка EXPLAIN ANALYZE

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

Промт:

Ты — эксперт по PostgreSQL. Проанализируй вывод EXPLAIN (ANALYZE, BUFFERS) для запроса ниже. Определи самое дорогое место, объясни причину (seq scan, nested loop, sort) и предложи 3 варианта оптимизации с ожидаемым эффектом.

Запрос: SELECT * FROM orders WHERE user_id = 42 AND created_at > '2026-01-01';
План: [вставьте вывод EXPLAIN]

Пример результата:

Seq Scan on orders  (cost=0.00..15432.00 rows=1 width=100) (actual time=120.123..450.678 rows=5 loops=1)
  Filter: ((user_id = 42) AND (created_at > '2026-01-01'))
  Rows Removed by Filter: 999995

AI укажет, что отсутствует индекс, и предложит: CREATE INDEX CONCURRENTLY idx_orders_user_created ON orders (user_id, created_at);. Ожидаемое время выполнения сократится с 450 мс до 0.5 мс.

2. Генерация индексов на основе реальной нагрузки

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

Промт:

У меня есть таблица users (id, email, created_at, last_login, status). Проанализируй частые запросы из pg_stat_statements (топ-10 по total_time). Предложи оптимальные индексы, учитывая порядок колонок и включение (INCLUDE). Объясни, почему каждый индекс улучшит производительность.

Топ запросов: [список]

Пример результата: Для запроса SELECT * FROM users WHERE status = 'active' ORDER BY last_login DESC LIMIT 100; AI предложит:

CREATE INDEX idx_users_status_lastlogin ON users (status, last_login DESC) INCLUDE (email);

Это позволит использовать index-only scan и ускорить выборку в 10–20 раз.

3. Рефакторинг медленных JOIN

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

Промт:

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

Исходный запрос: SELECT ... FROM orders o JOIN users u ON o.user_id = u.id JOIN products p ON o.product_id = p.id WHERE u.status = 'active' AND p.category = 'electronics';

Пример результата: AI предложит заменить JOIN на EXISTS или вынести фильтрацию в CTE:

WITH active_users AS (SELECT id FROM users WHERE status = 'active'),
     electronics_products AS (SELECT id FROM products WHERE category = 'electronics')
SELECT o.* FROM orders o
WHERE o.user_id IN (SELECT id FROM active_users)
  AND o.product_id IN (SELECT id FROM electronics_products);

Это уменьшит вложенные циклы и ускорит запрос в 3–5 раз.

4. Партиционирование большой таблицы

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

Промт:

У меня есть таблица events (id, user_id, event_type, created_at) с 2 млрд строк. Предложи стратегию партиционирования по диапазону дат (RANGE) с шагом месяц. Напиши SQL для создания партиций и миграции данных без блокировки. Учти, что PostgreSQL 16.

Пример результата:

CREATE TABLE events_partitioned (LIKE events INCLUDING ALL) PARTITION BY RANGE (created_at);
CREATE TABLE events_2026_01 PARTITION OF events_partitioned FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
-- И так далее для каждого месяца.
-- Затем: INSERT INTO events_partitioned SELECT * FROM events; (можно батчами)

AI также напомнит про pg_partman для автоматизации.

5. Настройка VACUUM и autovacuum

Задача: Уменьшить bloat и предотвратить раздувание таблиц.

Промт:

Проанализируй текущие настройки autovacuum для таблицы orders (100 млн строк, 20% обновлений в день). Предложи оптимальные параметры autovacuum_vacuum_scale_factor, autovacuum_vacuum_threshold, autovacuum_analyze_scale_factor. Объясни, как это повлияет на производительность.

Пример результата: AI порекомендует снизить scale_factor до 0.01 и увеличить threshold до 1000, чтобы VACUUM запускался чаще и не откладывался. Это уменьшит bloat с 40% до 5%.

6. Миграции без downtime

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

Промт:

Как добавить NOT NULL колонку в таблицу users (10 млн строк) без остановки приложения? Опиши пошаговый план с использованием ALTER TABLE ... ADD COLUMN с DEFAULT, затем заполнение батчами и установка NOT NULL.

Пример результата:

ALTER TABLE users ADD COLUMN age INT DEFAULT 0; -- быстро, без перезаписи
UPDATE users SET age = 18 WHERE age IS NULL; -- батчами по 10000
ALTER TABLE users ALTER COLUMN age SET NOT NULL;

AI предупредит, что в PostgreSQL 11+ добавление колонки с DEFAULT не требует перезаписи.

7. Оптимизация сортировки и LIMIT

Задача: Ускорить запросы с ORDER BY и LIMIT на больших таблицах.

Промт:

Запрос: SELECT * FROM logs WHERE level = 'error' ORDER BY timestamp DESC LIMIT 100; выполняется 2 секунды. Предложи индекс, который ускорит сортировку и выборку.

Пример результата: AI предложит:

CREATE INDEX idx_logs_level_timestamp ON logs (level, timestamp DESC);

Это позволит использовать index scan без сортировки.

8. Анализ блокировок и deadlocks

Задача: Найти причину взаимоблокировок.

Промт:

В логах PostgreSQL появились deadlock detected. Проанализируй вывод pg_locks и pg_stat_activity. Предложи, как переписать транзакции, чтобы избежать deadlock.

Пример результата: AI покажет, что транзакции блокируют строки в разном порядке, и предложит унифицировать порядок обновления или использовать SELECT ... FOR UPDATE SKIP LOCKED.

9. Использование pg_stat_statements для поиска топ-запросов

Задача: Выявить самые ресурсоёмкие запросы.

Промт:

Напиши запрос к pg_stat_statements, который покажет топ-5 запросов по total_time, среднему времени выполнения и количеству вызовов. Исключи запросы самой статистики.

Пример результата:

SELECT query, calls, total_time, mean_time, rows
FROM pg_stat_statements
WHERE query NOT LIKE '%pg_stat_statements%'
ORDER BY total_time DESC
LIMIT 5;

10. Настройка work_mem и maintenance_work_mem

Задача: Ускорить сортировки и VACUUM.

Промт:

Как подобрать work_mem для сервера с 64 ГБ RAM, если часто выполняются сложные сортировки? Предложи формулу и протестируй на примере.

Пример результата: AI порекомендует начать с 4 МБ на соединение, увеличивая до 64 МБ для аналитических запросов, и использовать SET LOCAL work_mem = '64MB'; для конкретных сессий.

11. Оптимизация запросов с LIKE и полнотекстовым поиском

Задача: Ускорить поиск по шаблону.

Промт:

Запрос: SELECT * FROM articles WHERE title LIKE '%postgres%'; выполняется 5 секунд на 1 млн строк. Предложи использовать GIN-индекс и полнотекстовый поиск.

Пример результата: AI предложит:

CREATE INDEX idx_articles_title_fts ON articles USING GIN (to_tsvector('russian', title));
SELECT * FROM articles WHERE to_tsvector('russian', title) @@ to_tsquery('postgres');

12. Мониторинг и автоматизация с AI

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

Промт:

Напиши скрипт на Python, который каждые 5 минут собирает pg_stat_database, pg_stat_user_tables и отправляет в Prometheus. Добавь алерт, если bloat > 20%.

Пример результата: AI сгенерирует код с использованием psycopg2 и prometheus_client, а также дашборд для Grafana.

Выводы

Эти 12 промтов покрывают ключевые сценарии оптимизации PostgreSQL — от чтения планов до партиционирования. Используйте их как отправную точку, адаптируя под свою схему. Помните: AI не заменяет экспертизу, но ускоряет рутину. Начните с EXPLAIN ANALYZE, затем переходите к индексам и партиционированию. Для глубокого погружения рекомендую официальную документацию PostgreSQL и блог Depesz. Экспериментируйте на тестовой базе и измеряйте эффект. Ускорение в разы — реально.

← Все статьи

Комментарии