lightdb-pq_distribute hint
Posted 紫无之紫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lightdb-pq_distribute hint相关的知识,希望对你有一定的参考价值。
文章目录
LightDB pq_distribute hint
LightDB 从 22.3 版本开始支持 oralce 的 pq_distribute hint, 目前只支持 none,broadcast
和 hash,hash
两种模式,其中hash,hash
不生效。
一. LightDB parallel join 介绍
lightdb 并发 join 支持两种模式,一种是只有外表并发,一种则内外表都可以并发(只支持hash join)。
1.1 外表并发
此模式下只有外表并发,内表广播,每个worker都会访问全量内表。Nestloop, mergejoin 只能采用此模式,hashjoin 可以采用此模式。以 hashjoin 为例,每个 worker 都会根据内表生成一个全量的hash表,每个 worker的 hash 表都相同。
在 explain 下显示为 Hash Join
QUERY PLAN
---------------------------------------------
Gather
Workers Planned: 3
-> Hash Join
Hash Cond: (t1.id = t2.id)
-> Parallel Seq Scan on t1 @"lt#0"
-> Hash
-> Seq Scan on t2 @"lt#0"
(7 rows)
这种模式类似 oracle 的 none,broadcast 模式
1.2 内外表都并发 Parallel Hash Join
此模式下外表并发,内表也支持并发,目前只有 hashjoin 支持。 会对内表并发的生成一个共享的 hash 表。需要等待内表生成完共享的 hash 表后,才能开始并发 join。
在 explain 下显示为 Parallel Hash Join
QUERY PLAN
---------------------------------------------------
Gather
Workers Planned: 3
-> Parallel Hash Join
Hash Cond: (t2.id = t1.id)
-> Parallel Seq Scan on t2 @"lt#0"
-> Parallel Hash
-> Parallel Seq Scan on t1 @"lt#0"
(7 rows)
在oracle中没有类似的模式
1.3 note
oracle 中的 hash, hash 模式在 LightDB 中不支持,故只支持语法,oracle 的其他模式在 23.1 暂不支持,计划后续版本支持,至少会支持语法(为了更好迁移)。
二. hint 介绍及使用
2.1 语法
pq_distribute(inner_table outer_distribution inner_distribution)
- inner_table: 指定 join 中的内表名
- outer_distribution:指定外表的模式
- inner_distribution:指定内表的模式
outer_distribution,inner_distribution
可选的组合目前有:none, broadcast
;hash, hash
。其中hash, hash
只支持语法。
- none, broadcast: 表示外表并发,内表广播
- hash, hash: 在 oracle 中表示 使用 hash 函数对内外表数据进行分区,然后一一映射,一一关联。在 LightDB 中不支持此模式。
使用 pq_distribute hint 只是让优化器在选择指定的表作为关联的内表且关联模式为parallel hash join 时,改变 j改变模式为none, broadcast。
2.2 使用案例
2.2.1 准备
create table t1 (id int, val text);
create table t2 (id int, val text);
2.2.2 测试案例
-
使用
/*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
来使 join 选择 parallel join。 -
使用
leading(t1 t2) hashjoin(t1 t2)
来指定 join 为 hashjoin 并指定 join 顺序 -
使用
pq_distribute(t2 none broadcast)
来使用外表并发,内表广播的方式。
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
lightdb@lt_test-# EXPLAIN (COSTS false) SELECT /*+ leading(t1 t2) hashjoin(t1 t2)*/ * FROM t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------------
Gather
Workers Planned: 3
-> Parallel Hash Join
Hash Cond: (t1.id = t2.id)
-> Parallel Seq Scan on t1 @"lt#0"
-> Parallel Hash
-> Parallel Seq Scan on t2 @"lt#0"
(7 rows)
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
lightdb@lt_test-# EXPLAIN (COSTS false) select/*+leading(t1 t2) hashjoin(t1 t2) pq_distribute(t2 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------
Gather
Workers Planned: 3
-> Hash Join
Hash Cond: (t1.id = t2.id)
-> Parallel Seq Scan on t1 @"lt#0"
-> Hash
-> Seq Scan on t2 @"lt#0"
(7 rows)
lightdb@lt_test=#
- 在于 swap_join_inputs 一起用时,swap_join_inputs 生效的话,pq_distribute 也会生效(原先为parallel hashjoin)。这与 oracle 不同,在 oracle 中 swap_join_inputs 生效,但如果 pq_distribute 与 swap_join_inputs 指定的不是同一张表,则 pq_distribute 不会起效。
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
EXPLAIN (COSTS false) select/*+leading(t1 t2) hashjoin(t1 t2) pq_distribute(t1 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------------
Gather
Workers Planned: 3
-> Parallel Hash Join
Hash Cond: (t1.id = t2.id)
-> Parallel Seq Scan on t1 @"lt#0"
-> Parallel Hash
-> Parallel Seq Scan on t2 @"lt#0"
(7 rows)
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
EXPLAIN (COSTS false) select/*+leading(t1 t2) hashjoin(t1 t2) pq_distribute(t1 none broadcast) swap_join_inputs(t2)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------
Gather
Workers Planned: 3
-> Hash Join
Hash Cond: (t2.id = t1.id)
-> Parallel Seq Scan on t2 @"lt#0"
-> Hash
-> Seq Scan on t1 @"lt#0"
(7 rows)
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
EXPLAIN (COSTS false) select/*+leading(t1 t2) hashjoin(t1 t2) pq_distribute(t2 none broadcast) swap_join_inputs(t2)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------
Gather
Workers Planned: 3
-> Hash Join
Hash Cond: (t2.id = t1.id)
-> Parallel Seq Scan on t2 @"lt#0"
-> Hash
-> Seq Scan on t1 @"lt#0"
(7 rows)
lightdb@lt_test=#
- 如果没有指定 hashjoin 的顺序,没有使用 pq_distribute 时 t2 是内表,使用了 pq_distribute 后,执行计划还是Parallel Hash Join, 但内表变为了 t1, 看起来像是 pq_distribute 没起效。
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
EXPLAIN (COSTS false) select/*+hashjoin(t1 t2)pq_distribute(t2 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------------
Gather
Workers Planned: 3
-> Parallel Hash Join
Hash Cond: (t2.id = t1.id)
-> Parallel Seq Scan on t2 @"lt#0"
-> Parallel Hash
-> Parallel Seq Scan on t1 @"lt#0"
(7 rows)
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
EXPLAIN (COSTS false) select/*+hashjoin(t1 t2)pq_distribute(t1 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------------
Gather
Workers Planned: 3
-> Parallel Hash Join
Hash Cond: (t1.id = t2.id)
-> Parallel Seq Scan on t1 @"lt#0"
-> Parallel Hash
-> Parallel Seq Scan on t2 @"lt#0"
(7 rows)
lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
EXPLAIN (COSTS false) select/*+hashjoin(t1 t2)pq_distribute(t1 none broadcast) pq_distribute(t2 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
QUERY PLAN
---------------------------------------------
Gather
Workers Planned: 3
-> Hash Join
Hash Cond: (t1.id = t2.id)
-> Parallel Seq Scan on t1 @"lt#0"
-> Hash
-> Seq Scan on t2 @"lt#0"
(7 rows)
lightdb@lt_test=#
以上是关于lightdb-pq_distribute hint的主要内容,如果未能解决你的问题,请参考以下文章
Default value for parameters with a class type hin