Параллельные запросы в PostgreSQL: Настройка parallel workers и производительности
- Многопоточные сервера с 64+ ядрами CPU загружены только на 1-2 ядра при выполнении тяжелых отчетов.
- Аналитические запросы (OLAP) сканируют сотни гигабайт в один поток в течение десятков минут.
- Длительное построение B-Tree индексов и медленный фоновый autovacuum.
1. Архитектура параметров параллелизма в postgresql.conf
Рассчитайте параметры исходя из физического количества ядер CPU (пример для 16-ядерного выделенного сервера СУБД):
# Общий лимит фоновых процессов всех типов
max_worker_processes = 16
# Максимальное число воркеров, выделяемых под параллельные запросы всех клиентов
max_parallel_workers = 12
# Максимальное число воркеров на один узел одного SQL-запроса
max_parallel_workers_per_gather = 4
# Лимит воркеров для параллельного создания индексов (CREATE INDEX) и VACUUM
max_parallel_maintenance_workers = 4
# Порог размера таблицы для запуска параллельного сканирования
min_parallel_table_scan_size = 8MB
min_parallel_index_scan_size = 512kB2. Применение параметров и тестирование плана
SELECT pg_reload_conf();
-- Принудительное поощрение параллелизма в тестовой сессии
SET force_parallel_mode = on;
EXPLAIN (ANALYZE, BUFFERS)
SELECT count(*), avg(amount) FROM large_fact_table WHERE created_at >= '2024-01-01';В выводе плана должны появиться узлы: Gather, Parallel Seq Scan или Parallel Index Scan со строкой Workers Planned: 4, Workers Launched: 4.
3. Тюнинг индивидуальных таблиц
-- Форсировать параллельные воркеры для конкретной крупной таблицы
ALTER TABLE large_fact_table SET (parallel_workers = 6); Частые вопросы (FAQ)
Почему параллелизм не включается для определенных запросов?
Параллелизм блокируется, если запрос использует параллельно-небезопасные функции (PARALLEL UNSAFE), модифицирует данные (INSERT/UPDATE/DELETE в некоторых версиях), использует курсоры или если таблица меньше min_parallel_table_scan_size.
Как параллельные воркеры расходуют work_mem?
Каждый параллельный worker процесс аллоцирует свой собственный изолированный объем work_mem. Если запрос использует 4 воркера, потребление памяти на сортировку умножится на 4 (плюс процесс-лидер).
Помогает ли параллелизм для OLTP нагрузок (например, 1С:Предприятие)?
Для коротких транзакций OLTP накладные расходы на запуск и синхронизацию воркеров через Shared Memory снижают производительность. Параллелизм эффективен только для тяжелых аналитических выборок.
Что означает статус Workers Launched: 0 в EXPLAIN плане?
Планировщик запланировал параллельное выполнение, но в момент запуска в пуле ядра не было свободных слотов из-за исчерпания глобального лимита max_parallel_workers.