План запросов Postgres постоянно меняется - иногда выполнение запроса занимает минуту, а иногда не завершается

У меня огромный SQL-запрос. Вероятно, 15-20 столов. Есть 6-7 подзапросов, которые снова объединяются. Этот запрос чаще всего выполняется за минуту и ​​возвращает 5 миллионов записей.

Таким образом, даже если этот запрос написан плохо, у него есть план запроса, который завершает его за минуту. Я гарантировал, что запрос действительно выполнялся и не использовал кэшированные результаты.

Иногда план запроса изматывается, а затем он никогда не заканчивается. Я провожу анализ вакуума каждую ночь на таблицах, участвующих в запросе. Work_memory в настоящее время установлен на 200 МБ. Я попытался увеличить это до 2 ГБ. Я не сталкивался с ошибкой запроса, когда work_memory был 2 ГБ. Но когда я уменьшил его и запустил запрос, он запутался. Теперь, когда я увеличил его до 2 ГБ, запрос все еще запутался. Это как-то связано с тем, что план запроса не обновляется с новой настройкой? Я попытался отказаться от плана на моей сессии.

На данный момент я могу думать только о work_mem и вакуумном анализе. Любые другие факторы, которые могут повлиять на бесперебойно выполняемый запрос, который возвращает результаты за минуту и ​​ничего не возвращает?

Дайте мне знать, если вам нужно больше информации о каких-либо настройках? или сам запрос? Я тоже могу вставить план... Но запрос и план или слишком большой для вставки здесь..

1 ответ

Если есть больше чем geqo_treshold (обычно 12) записей в таблице диапазонов, сработает генетический оптимизатор, что часто приводит к случайному поведению, как описано в вопросе. Вы можете решить это:

  • увеличение geqo_limit
  • переместите часть вашей таблицы референс в CTE. Если у вас уже есть несколько подзапросов, продвиньте один (или несколько) из них в CTE. Это своего рода черное искусство, позволяющее идентифицировать кластеры таблиц в вашем запросе, которые поместятся в компактном CTE (с относительно небольшим числом кортежей результатов и не слишком большим количеством ключевых ссылок на внешний запрос).

Установка слишком высокого значения geqo_treshold (вероятно, слишком высокое значение 20) приведет к тому, что планировщику потребуется много времени для оценки всех планов. (количество планов увеличивается в основном экспоненциально по сравнению с количеством RTE) Если вы ожидаете, что вашему запросу потребуется несколько минут для выполнения, несколько секунд времени планирования, вероятно, не принесут вреда.

Другие вопросы по тегам