Тюнинг random_page_cost и effective_cache_size в PostgreSQL для NVMe
- Оптимизатор упорно выбирает медленный
Seq ScanвместоIndex Scanна быстрых твердотельных накопителях. - Заниженная оценка доступной памяти кэша заставляет СУБД строить планы с неэффективными соединениями Hash Join.
- Высокое время генерации и исполнения планов запросов на современном Enterprise-оборудовании.
1. Тюнинг стоимостных весов дискового ввода-вывода
По умолчанию random_page_cost = 4.0 рассчитан на старые механические жесткие диски (HDD). Для Enterprise NVMe накопителей случайное чтение практически равно последовательному:
# /etc/postgresql/16/main/postgresql.conf
# Базовая стоимость последовательного чтения блока (эталон)
seq_page_cost = 1.0
# Стоимость случайного чтения блока (1.1 для NVMe, 1.5 для SATA SSD)
random_page_cost = 1.12. Расчет параметра effective_cache_size
Параметр сообщает планировщику, какой объем памяти (shared_buffers + дисковый кэш ОС Linux) доступен для кэширования таблиц и индексов. Рекомендуемое значение: 50%–75% от общего объема физической RAM сервера.
# Для сервера с 64 ГБ RAM:
effective_cache_size = 48GB
# Для сервера со 128 ГБ RAM:
effective_cache_size = 96GB3. Сопутствующие параметры оптимизатора под NVMe
# Число одновременно выполняемых операций ввода-вывода (до 200-300 для NVMe)
effective_io_concurrency = 200
# Стоимость обработки кортежа процессором
cpu_tuple_cost = 0.01
cpu_index_tuple_cost = 0.0054. Применение и валидация изменений
SELECT pg_reload_conf();
-- Проверка изменений в тестовом запросе
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 45120; Частые вопросы (FAQ)
Выделяет ли PostgreSQL физическую память под effective_cache_size?
Нет. Параметр effective_cache_size является исключительно оценочной величиной для оптимизатора (Cost-Based Optimizer) и не аллоцирует реальную оперативную память.
Что произойдет, если установить random_page_cost равным 1.0?
Планировщик сочтет произвольное чтение страниц по индексам таким же 'дешевым', как последовательное чтение. Это практически полностью исключит выбор Seq Scan в пользу Index Scan даже там, где это не оптимально.
Как проверить, сколько памяти реально занято кэшем ОС Linux?
Выполните команду free -m в терминале ОС и обратите внимание на столбец buff/cache.
Как влияет effective_io_concurrency на производительность?
Он указывает ядру PostgreSQL, сколько асинхронных запросов чтения страниц по Bitmap Heap Scan можно инициировать параллельно контроллеру диска через posix_fadvise.