generic_plan_fuzz_factor — это параметр конфигурации, который есть только в СУБД Postgres Pro (в ванильном PostgreSQL он отсутствует). Он добавляет «допуск» при сравнении стоимости общего (generic) и специализированного (custom) планов выполнения запроса, чтобы избежать частой смены планов и сделать поведение планировщика более стабильным.
📖 Назначение
Параметр управляет тем, насколько «уверенно» планировщик предпочитает универсальный, общий план выполнения запроса (generic plan) специализированному (custom plan).
Когда СУБД получает параметризованный запрос (например, через PREPARE), она может построить план либо универсальный (подходящий для любых значений), либо специализированный (оптимизированный под конкретные переданные параметры). Сравнивая их итоговую стоимость, планировщик применяет коэффициент generic_plan_fuzz_factor к стоимости общего плана, добавляя «допуск», который делает выбор более стабильным. Без этого допуска планировщик был бы вынужден строго выбирать план с наименьшей стоимостью, что могло бы приводить к постоянным «метаниям» между планами при незначительных колебаниях статистики или параметров.
🛠️ Статус по умолчанию
· Значение по умолчанию: 1
· Тип значения: double (число с плавающей точкой)
· Контекст установки: user (можно изменять в рамках сессии)
🎯 Зачем это нужно
Основная цель — обеспечить стабильность и предсказуемость планов выполнения. Значение по умолчанию (1) даёт небольшое предпочтение общему плану. Это помогает решить несколько проблем:
1. Избежать «дрожания» планов: Если стоимости общего и специализированного планов почти одинаковы, даже незначительное изменение статистики может заставить планировщик переключиться с одного на другой. Это создаёт непредсказуемую производительность. Параметр добавляет «допуск», который подавляет такие переключения.
2. Повысить попадание в кеш планов: Общие планы (generic plans) кешируются и могут переиспользоваться для разных параметров, что экономит ресурсы на планировании. Специализированные планы (custom plans) не кешируются и требуют построения заново при каждом вызове. Поощряя использование общего плана, generic_plan_fuzz_factor способствует более эффективному использованию кеша.
📊 Стратегия выбора плана
Параметр определяет порог, с которым сравнивается разница в стоимости между общим и специализированным планами:
· generic_plan_fuzz_factor = 1 (по умолчанию): Планировщик выбирает общий план, если его стоимость не превышает стоимость специализированного плана более чем в 1 раз (т.е. если они равны, выбирается общий план).
· generic_plan_fuzz_factor > 1: Порог выше, и планировщик чаще будет отдавать предпочтение общему плану, даже если его оценочная стоимость несколько выше, чем у специализированного. Это усиливает стабильность и использование кеша.
· generic_plan_fuzz_factor < 1 (например, 0.9): Порог ниже 1. Это делает планировщика менее «терпимым» к неоптимальности общего плана. Если его стоимость начинает превышать стоимость специализированного плана, система быстрее откажется от общего плана в пользу специализированного.
🤝 Взаимодействие с plan_cache_mode
Параметр generic_plan_fuzz_factor работает в связке с другим важным параметром — plan_cache_mode:
· Если plan_cache_mode установлен в auto (по умолчанию), планировщик самостоятельно решает, какой план использовать — общий или специализированный. В этом случае generic_plan_fuzz_factor активно участвует в процессе сравнения стоимостей и влияет на итоговый выбор.
· Если plan_cache_mode установлен в force_generic_plan, планировщик принудительно всегда использует общий план, полностью игнорируя значение generic_plan_fuzz_factor.
📝 Примеры использования
1. Установка глобально в postgresql.conf:
# Сделать использование общего плана более предпочтительным
generic_plan_fuzz_factor = 2.0
Эта настройка заставит планировщик выбирать общий план, только если его стоимость не более чем в 2 раза превышает стоимость специализированного.
2. Изменение параметра в рамках конкретной сессии:
-- В рамках этой сессии отключаем «допуск» для общего плана
SET generic_plan_fuzz_factor = 0;
✨ Резюме
generic_plan_fuzz_factor в Postgres Pro — это тонкий инструмент для смещения баланса между стабильностью (использование кешированных общих планов) и оптимальностью (построение специализированного плана под конкретные параметры). Его умелое использование может помочь стабилизировать производительность систем с высокими требованиями к предсказуемости, избегая проблем из-за внезапной смены планов запросов.