Broadcast Motion vs Redistribute Motion: как данные летят между сегментами Greenplum
EXPLAIN ANALYZE
SELECT fact.customer_id, sum(fact.amount)
FROM fact_orders fact
JOIN dim_customer_scoring scoring
ON fact.customer_id = scoring.customer_id
GROUP BY fact.customer_id;
Gather Motion 96:1 (slice3; segments: 96) (cost=0.00..892345.12 rows=1 width=48)
(actual time=41823.441..41823.512 rows=1 loops=1)
-> HashAggregate (cost=845210.30..845210.31 rows=1 width=48)
(actual time=41756.203..41756.204 rows=1 loops=1)
Group Key: fact.customer_id
-> Hash Join (cost=312500.00..812340.00 rows=1310000 width=32)
(actual time=8210.552..40982.117 rows=1298742 loops=1)
Hash Cond: (fact.customer_id = scoring.customer_id)
-> Redistribute Motion 96:96 (slice2; segments: 96)
(cost=0.00..401200.00 rows=8400000 width=24)
(actual time=0.041..21432.884 rows=8391204 loops=1)
Hash Key: fact.customer_id
-> Seq Scan on fact_orders fact
(cost=0.00..250340.00 rows=8400000 width=24)
(actual time=0.012..3452.201 rows=8391204 loops=1)
-> Hash (cost=185300.00..185300.00 rows=1310000 width=16)
(actual time=8195.312..8195.312 rows=1298742 loops=1)
-> Redistribute Motion 96:96 (slice1; segments: 96)
(cost=0.00..185300.00 rows=1310000 width=16)
(actual time=0.038..6821.442 rows=1298742 loops=1)
Hash Key: scoring.customer_id
-> Seq Scan on dim_customer_scoring scoring
(cost=0.00..92100.00 rows=1310000 width=16)
(actual time=0.009..1103.221 rows=1298742 loops=1)
Planner: Pivotal Optimizer (GPORCA)
Planning time: 24.671 ms
(slice1) Executor memory: 51302K bytes avg x 96 workers, 52481K bytes max (seg17).
(slice2) Executor memory: 118204K bytes avg x 96 workers, 121890K bytes max (seg33).
Total runtime: 41892.667 ms -- смотрим текущий ключ дистрибуции обеих таблиц
SELECT localoid::regclass AS table_name, attrnums
FROM gp_distribution_policy
WHERE localoid IN ('fact_orders'::regclass, 'dim_customer_scoring'::regclass);
-- меняем ключ дистрибуции таблицы скоринга на customer_id
ALTER TABLE dim_customer_scoring
SET DISTRIBUTED BY (customer_id);
-- обновляем статистику после физического перераспределения данных
VACUUM ANALYZE dim_customer_scoring; Gather Motion 96:1 (slice1; segments: 96) (cost=0.00..612100.20 rows=1 width=48)
(actual time=3241.552..3241.601 rows=1 loops=1)
-> HashAggregate (cost=598200.10..598200.11 rows=1 width=48)
(actual time=3198.220..3198.221 rows=1 loops=1)
Group Key: fact.customer_id
-> Hash Join (cost=210400.00..585310.00 rows=1310000 width=32)
(actual time=612.204..2981.552 rows=1298742 loops=1)
Hash Cond: (fact.customer_id = scoring.customer_id)
-> Seq Scan on fact_orders fact
(cost=0.00..250340.00 rows=8400000 width=24)
(actual time=0.010..1102.334 rows=8391204 loops=1)
-> Hash (cost=92100.00..92100.00 rows=1310000 width=16)
(actual time=608.552..608.552 rows=1298742 loops=1)
-> Seq Scan on dim_customer_scoring scoring
(cost=0.00..92100.00 rows=1310000 width=16)
(actual time=0.008..401.221 rows=1298742 loops=1)
Planner: Pivotal Optimizer (GPORCA)
Planning time: 18.204 ms
(slice1) Executor memory: 42108K bytes avg x 96 workers, 43012K bytes max (seg0).
Total runtime: 3298.114 ms SELECT gp_segment_id, count(*)
FROM fact_orders
GROUP BY gp_segment_id
ORDER BY count(*) DESC
LIMIT 10; Эксперт ДБ-сервис