Вступить в клуб →
сложнаявопросSQL и оптимизация запросов

Фильтр по функции над колонкой отключил отсечение секций

Таблица dds.fct_events в PostgreSQL — 800 млн строк, секционирована по месяцам колонки event_ts (timestamp), по этой же колонке есть индекс. Отчёт за один день собирается шесть минут, в плане — последовательное чтение всех секций:

SELECT count(*)
FROM dds.fct_events
WHERE to_char(event_ts, 'YYYY-MM-DD') = '2026-08-01';

У коллеги похожий отчёт за тот же день отрабатывает за секунды. В чём причина и как переписать условие?

  • Дело в статистике: планировщик не знает селективность выражения и считает, что условие вернёт значительную часть таблицы; после ANALYZE и увеличения детальности статистики по event_ts он переключится на чтение по индексу.
  • Отсечение секций работает только при явном обращении к нужной секции: запрос к родительской таблице всегда читает все части, поэтому отчёт надо направлять прямо в fct_events_2026_08.
  • Колонка завёрнута в функцию, поэтому предикат не сопоставляется ни с ключом секционирования, ни с индексом по event_ts. Условие надо записать диапазоном по самой колонке: event_ts >= '2026-08-01' AND event_ts < '2026-08-02'.
  • Причина в форматирующей функции: to_char возвращает text, и сравнение идёт по строке. Достаточно заменить её на приведение типа event_ts::date = '2026-08-01' — приведение планировщик разворачивает в диапазон, и отсечение заработает.

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела