Оценка 2 тысячи, факт 10 тысяч: зависимые колонки
Вопрос
В customers город однозначно определяет регион (Москва всегда ЦФО). Почему планировщик ждёт 1997 строк, а пришло 10 000, и что поможет?
Aggregate (cost=1292.99..1293.00 rows=1 width=8) (actual time=3.837..3.838 rows=1 loops=1)
-> Seq Scan on customers (cost=0.00..1288.00 rows=1997 width=0) (actual time=0.005..3.363 rows=10000 loops=1)
Filter: ((city = 'Москва'::text) AND (region = 'ЦФО'::text))
Rows Removed by Filter: 40000
Planning Time: 0.266 ms
Execution Time: 3.876 ms
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Статистика устарела; поможет
VACUUM FULL customersс пересборкой - Условия сочтены независимыми; поможет
CREATE STATISTICS (dependencies)правильный ответ - Оценки для
textнеточные; поможет перевод колонок вvarchar(64) - Seq Scan не умеет оценивать строки; поможет индекс по
(city, region)
Разбор
Обычная статистика собирается по каждой колонке отдельно, и для city = 'Москва' AND region = 'ЦФО' планировщик перемножает доли: 0,2 × 0,2 × 50 000 ≈ 2000. Но условия зависимы: если город Москва, то регион всегда ЦФО, и реальная доля 0,2. Расширенная статистика CREATE STATISTICS customers_city_region (dependencies) ON city, region FROM customers с последующим ANALYZE учитывает функциональную зависимость: на этих данных оценка становится 9980. Здесь ошибка безобидна, но в соединениях заниженная оценка приводит к Nested Loop там, где нужен Hash Join. VACUUM FULL перезаписывает таблицу и статистику не меняет, тип строки на оценку не влияет, индекс сам по себе статистику не исправит.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Перепиши фильтр по месяцу под индекс
Следующий вопрос
Что значит Batches: 2 у узла Hash