Что значит Batches: 2 у узла Hash
Вопрос
Запрос выполнялся с work_mem = '1MB'. Что означает Batches: 2 у узла Hash и как это обычно лечат?
HashAggregate (cost=37048.22..37048.29 rows=5 width=49) (actual time=577.354..577.359 rows=5 loops=1)
Group Key: c.city
Batches: 1 Memory Usage: 24kB
-> Hash Join (cost=1956.00..32048.22 rows=1000000 width=24) (actual time=11.246..437.444 rows=1000000 loops=1)
Hash Cond: (o.customer_id = c.id)
-> Seq Scan on orders o (cost=0.00..17408.00 rows=1000000 width=11) (actual time=0.014..102.939 rows=1000000 loops=1)
-> Hash (cost=1038.00..1038.00 rows=50000 width=21) (actual time=11.087..11.088 rows=50000 loops=1)
Buckets: 32768 Batches: 2 Memory Usage: 1633kB
-> Seq Scan on customers c (cost=0.00..1038.00 rows=50000 width=21) (actual time=0.003..3.865 rows=50000 loops=1)
Planning Time: 1.089 ms
Execution Time: 577.587 ms
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Хеш-таблицу собирали два параллельных воркера; лечить ничего не нужно
- Таблица
customersпрочитана дважды из-за плохой статистики; нуженANALYZE - Хеш не влез в память, соединение разбито на 2 партии; поднять
work_mem - В хеше слишком много коллизий; нужно увеличить число
Bucketsвручнуюправильный ответ
Разбор
Hash Join строит хеш-таблицу по меньшей стороне. Если она не влезает в лимит памяти (work_mem × hash_mem_multiplier, множитель по умолчанию 2 начиная с PostgreSQL 15), строки делятся на партии (batches): одна обрабатывается в памяти, остальные пишутся во временные файлы и дочитываются потом. Batches: 1 значит, что всё поместилось. Лечат точечным SET work_mem для тяжёлого отчёта, выбором меньшего числа колонок (в хеш попадают только нужные) или фильтрацией до соединения. Параллельность в плане видна по узлам Gather и Parallel, здесь их нет. Число бакетов PostgreSQL подбирает сам, а повторного чтения таблицы план не показывает.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Оценка 2 тысячи, факт 10 тысяч: зависимые колонки
Следующий вопрос
Как читать loops во вложенном цикле