DeepLearning Blog

Топ настрок для оптимизации запросов в postgres

Published March 31, 2026, 8:33 a.m. by railot116

Вы абсолютно правы, извините за путаницу. Вы просили именно настройки PostgreSQL (параметры в postgresql.conf), которые влияют на оптимизацию запросов, а не практики написания SQL.

Вот топ-10 настроек PostgreSQL, которые напрямую влияют на то, как планировщик оптимизирует и выполняет запросы:


1. enable_* — переключатели методов доступа

Самый прямой способ влиять на планировщик. Эти настройки включают/отключают конкретные типы планов:

Настройка Что отключает Когда использовать
enable_seqscan Последовательное сканирование Если планировщик упорно выбирает Seq Scan там, где индекс быстрее
enable_indexscan Индексное сканирование Для тестирования или если индекс вредит
enable_indexonlyscan Только индексное скачивание SELECT count(*) с индексом
enable_bitmapscan Битовое сканирование При переоценке стоимости комбинированных индексов
enable_hashjoin Hash Join Если Hash Join жрет всю память
enable_mergejoin Merge Join Принуждение к nested loop
enable_nestloop Nested Loop Запрет для больших таблиц

Пример использования:

-- Временно запретить Seq Scan для конкретного запроса
SET enable_seqscan = off;
SELECT * FROM huge_table WHERE id = 12345;
SET enable_seqscan = on;

Рекомендация: Не трогайте глобально. Используйте для отладки или в сессии.


2. random_page_cost — стоимость случайного доступа

Влияет на выбор между Index Scan (случайный доступ) и Seq Scan (последовательный).

Значение Эффект
1.0 Случайный доступ стоит как последовательный (очень быстрый SSD)
1.1 – 2.0 Быстрые NVMe/SSD
4.0 (по умолчанию) HDD / медленный диск
> 10 Очень медленный диск

Проблема: На современных SSD стандартное значение 4.0 слишком высокое → планировщик недооценивает Seq Scan и переоценивает Index Scan.

Рекомендация:
- NVMe/PCIe SSD: 1.1 – 1.5
- SATA SSD: 2.0 – 3.0
- HDD: оставьте 4.0


3. effective_cache_size

Влияет на оценку стоимости Seq Scan. Завышение → планировщик чаще выбирает Seq Scan (думая, что данные уже в кеше). Занижение → чаще выбирает Index Scan.

Рекомендация: 50-75% от ОЗУ.


4. cpu_tuple_cost и cpu_operator_cost

Стоимость обработки одной строки и одной операции сравнения. Влияют на выбор между разными типами соединений и фильтрацией.

Параметр По умолчанию Рекомендация
cpu_tuple_cost 0.01 0.003 – 0.01 (на быстрых CPU)
cpu_operator_cost 0.0025 0.001 – 0.0025

Когда менять: Если у вас очень быстрые CPU и медленные диски, уменьшение этих параметров сделает CPU-операции "дешевле" в глазах планировщика.


5. join_collapse_limit

Ограничивает, как далеко планировщик может переписывать JOIN-ы.

-- Пример: планировщик может переставить порядок JOIN-ов
SELECT * FROM a JOIN b ON ... JOIN c ON ... JOIN d ON ...;
Значение Эффект
1 Запрещает перестановку JOIN-ов (используется только порядок, указанный в запросе)
8 (по умолчанию) Может переставлять до 8 таблиц
> 8 Больше вариантов, но дольше планирование

Рекомендация: Оставьте 8. Если у вас JOIN на 20+ таблиц, можно увеличить до 12-16, но это увеличит время планирования запроса.


6. from_collapse_limit

Аналогично join_collapse_limit, но для подзапросов с FROM (вьюхи, подзапросы).

Рекомендация: Обычно держат равным join_collapse_limit.


7. geqo (Genetic Query Optimizer)

Когда число таблиц в JOIN превышает geqo_threshold, PostgreSQL переключается с динамического программирования на генетический алгоритм.

Параметр Значение по умолчанию Рекомендация
geqo on Включен
geqo_threshold 12 Для OLTP: 12-16, для OLAP с большими JOIN: можно увеличить

Когда трогать: Если у вас частые запросы с JOIN на 10-15 таблиц и планировщик тратит на планирование секунды, можно повысить порог.


8. default_statistics_target — качество статистики

Определяет, сколько самых частых значений (MCV — Most Common Values) и гистограмму собирает ANALYZE.

Значение Размер pg_statistic Точность оценок
10 (по умолчанию) Маленький Базовая
100 Умеренный Хорошая
1000 Большой Очень точная
10000 Огромный Минутная

Влияние на запросы: Чем точнее статистика, тем лучше планировщик оценивает селективность фильтров и выбирает правильный индекс.

Рекомендация:
- Для важных таблиц: ALTER TABLE huge_table ALTER COLUMN status SET STATISTICS 1000;
- Глобально: default_statistics_target = 100 (хороший баланс)

Не забудьте: После изменения запустить ANALYZE.


9. effective_io_concurrency

Сколько одновременных операций ввода-вывода может выполнять диск. Влияет на оценку стоимости Bitmap Heap Scan.

Значение Тип диска
1 Один HDD
2-4 Несколько HDD в RAID
8-16 SATA SSD
16-32+ NVMe/PCIe SSD

Рекомендация: Установите для вашего типа диска. Для NVMe можно 32-64.


10. geqo_effort, geqo_generations, geqo_pool_size

Тонкая настройка генетического оптимизатора для сложных JOIN-запросов (более 20 таблиц). Если вы дошли до этих параметров — вы либо эксперт, либо у вас очень специфичная нагрузка.

Параметр По умолчанию Диапазон
geqo_effort 5 1-10
geqo_pool_size 0 (авто) 0-∞
geqo_generations 0 (авто) 0-∞

Рекомендация: Не трогайте без крайней необходимости.


Сводная таблица для быстрой настройки

Параметр HDD SATA SSD NVMe
random_page_cost 4.0 2.0 – 3.0 1.1 – 1.5
effective_io_concurrency 1-2 8-16 16-64
default_statistics_target 100 100 100-500
cpu_tuple_cost 0.01 0.005 – 0.01 0.003 – 0.005

Важное предупреждение

Никогда не меняйте enable_* настройки глобально в postgresql.conf без веской причины. Они созданы для:
- Отладки
- Сессионного изменения под конкретные запросы
- Временного "ручного управления" при ошибках планировщика

Для постоянной оптимизации используйте: random_page_cost, effective_cache_size, default_statistics_target, effective_io_concurrency.

  • Бонус

Вот топ-10 настроек PostgreSQL, которые чаще всего влияют на производительность и стабильность базы данных. Рекомендации даны для сервера с 16 ГБ ОЗУ .

1. shared_buffers — главный кеш

Это самый важный параметр. Он определяет, сколько памяти PostgreSQL выделит для кеширования данных в оперативной памяти, чтобы не читать их с диска при каждом запросе. * Рекомендация: 25% от ОЗУ (для 16 ГБ установите 4 ГБ) . * Требует: Перезапуска БД (postmaster) .

2. work_mem — память для сортировки

Отвечает за объем памяти для одной операции сортировки (ORDER BY, DISTINCT) или хеш-таблицы (JOIN). * Важно: Это значение умножается на количество одновременных операций. Если поставить слишком много, можно съесть всю память сервера . * Рекомендация: Для OLTP: 16–64 МБ. Для тяжелых аналитических запросов можно временно повысить через SET work_mem = '256MB'; .

3. effective_cache_size — оценка кеша ОС

Это не выделение памяти, а подсказка планировщику, сколько ОС тратит на дисковый кеш. Влияет на выбор между последовательным сканированием (Seq Scan) и индексным (Index Scan). * Рекомендация: 50–75% от ОЗУ (для 16 ГБ установите 8–12 ГБ) .

4. maintenance_work_mem — обслуживание БД

Используется для служебных операций: VACUUM, CREATE INDEX, REINDEX. Большое значение ускоряет эти процессы в разы. * Рекомендация: 5–10% от ОЗУ для серверов с большими таблицами (для 16 ГБ: 1–2 ГБ) .

5. max_connections — количество подключений

Лимит одновременных подключений к БД. Чем выше значение, тем больше памяти резервируется (даже для неактивных соединений). * Рекомендация: Для 16 ГБ лучше не ставить более 200–300. Если нужно больше, используйте пулер соединений (PgBouncer) . * Требует: Перезапуска БД .

6. wal_buffers — буфер журнала

Буфер для записи журнала предзаписи (WAL). Если происходит много мелких транзакций (INSERT/UPDATE), увеличение буфера снизит число операций ввода-вывода. * Рекомендация: 16–64 МБ. Если shared_buffers большой, Postgres часто сам назначает адекватное значение, но проверьте .

7. Настройки Checkpoint (checkpoint_timeout и checkpoint_completion_target)

Управляют сбросом "грязных" данных из памяти на диск. Цель — растянуть запись во времени, чтобы избежать пиковых нагрузок на диск. * Рекомендация:
* checkpoint_timeout: 15 минут (вместо стандартных 5) .
* checkpoint_completion_target: 0.9. Это значит, что сброс будет происходить в течение 90% от интервала (т.е. ~13.5 минут) .

8. max_parallel_workers_per_gather — параллелизм

Определяет, сколько ядер CPU может использовать один сложный запрос (для агрегации, JOIN больших таблиц). * Рекомендация: 2 или 4. Ориентируйтесь на количество ядер. На серверах с 8+ ядрами можно ставить 2 или 4, чтобы ускорить тяжелые запросы .

9. autovacuum и связанные пороги

Система очистки "мертвых" строк (после UPDATE/DELETE). Отключенный или медленный автовакуум — главная причина "раздувания" таблиц и падения производительности. * Рекомендация (базовая):
* Включен: on (по умолчанию).
* autovacuum_vacuum_scale_factor: 0.05–0.1 (чем активнее запись, тем меньше число, чтобы чистить чаще) .

10. Логирование медленных запросов

Позволяет находить узкие места без сторонних инструментов. * log_min_duration_statement: Установите в 1000 (1 секунда) или 500 (0.5 сек). Все запросы дольше этого порога попадут в лог . * pg_stat_statements: Расширение, которое собирает статистику по всем запросам. Обязательно включите его в shared_preload_libraries для детального анализа .

💡 Важное дополнение: Таймауты

Хотя их часто забывают, statement_timeout и idle_in_transaction_session_timeout критичны для стабильности. idle_in_transaction_session_timeout (например, 1 минута) убьет зависшие транзакции, которые могут блокировать очистку (VACUUM) и держать locks .

0.0
0 оценок
5★
0
4★
0
3★
0
2★
0
1★
0

Оставить отзыв

Нажмите на звезду для оценки от 1 до 5
Необязательно. Используется только для связи
0/2000

Комментарии

Все С ответами Проверенные Только 4-5★