lightdb22.2-增强对 oracle 常用 hint 的兼容(一)
表访问方式 (table access)
- 支持 oracle 的
full
建议优化器对表进行全表扫描获取数据, 与 lightdb 原先的seqscan
hint相同 - 支持 oracle 的
index
建议优化器对表进通过索引获取数据,与 lightdb 原先的indexscan
hint 相同
表关联方法(join method)
lightdb 支持3种表的join算法,分别为:hashjoin、nestloop以及mergejoin。
原先支持使用hashjoin
, nestloop
, mergejoin
来建议优化器对指定表的join使用特定算法。
现支持 oracle 的use_hash
, use_nl
,use_merge
, no_use_hash
, no_use_nl
, no_use_merge
来建议优化器对以指定的表作为内表的 join 使用特定算法。
要使用上述 oracle 语义需要设置lightdb_syntax_compatible_type
:
- 当
lightdb_syntax_compatible_type = 'oracle'
,use_xxx 与hashjoin
等 hint都是用来建议优化器对以指定的表作为内表的 join 使用特定算法,此时可以指定单表,当指定多个表时,效果相当于对每个表都使用use_xxx,比如:/*+use_hash(a b c)*/
即是/*+use_hash(a) use_hash(b) use_hash(c)*/
- 当
lightdb_syntax_compatible_type = 'off'
时,use_xxx 与hashjoin
等 hint 都是用来建议优化器对指定表的join使用特定算法,此时不能指定单表。
从下面的例子可以看出这两类 hint 的区别:
lightdb@postgres=# set lightdb_syntax_compatible_type = 'off';
lightdb@postgres=# EXPLAIN (COSTS false) SELECT /*+leading(t1 t2 t3) use_nl(t1 t2) use_merge(t1 t2 t3)*/* FROM t1, t2 ,t3 WHERE t1.id = t2.id and t2.id=t3.id;
LOG: pg_hint_plan:
used hint:
USE_NL(t1@lt#0 t2@lt#0)
USE_MERGE(t1@lt#0 t2@lt#0 t3@lt#0)
Leading(((t1@lt#0 t2@lt#0) t3@lt#0))
not used hint:
duplication hint:
error hint:
QUERY PLAN
----------------------------------------------------
Merge Join
Merge Cond: (t1.id = t3.id)
-> Nested Loop
-> Index Scan using t1_pkey on t1 @"lt#0"
-> Index Scan using t2_pkey on t2 @"lt#0"
Index Cond: (id = t1.id)
-> Index Scan using t3_pkey on t3 @"lt#0"
(7 rows)
lightdb@postgres=#
lightdb@postgres=# set lightdb_syntax_compatible_type = 'oracle';
lightdb@postgres=# EXPLAIN (COSTS false) SELECT /*+leading(t1 t2 t3) use_nl(t2) use_merge(t3)*/* FROM t1, t2 ,t3 WHERE t1.id = t2.id and t2.id=t3.id;
LOG: pg_hint_plan:
used hint:
USE_NL(t2@lt#0)
USE_MERGE(t3@lt#0)
Leading(((t1@lt#0 t2@lt#0) t3@lt#0))
not used hint:
duplication hint:
error hint:
QUERY PLAN
----------------------------------------------------
Merge Join
Merge Cond: (t1.id = t3.id)
-> Nested Loop
-> Index Scan using t1_pkey on t1 @"lt#0"
-> Index Scan using t2_pkey on t2 @"lt#0"
Index Cond: (id = t1.id)
-> Index Scan using t3_pkey on t3 @"lt#0"
(7 rows)
表关联顺序(join order)
lightdb 原先支持使用 leading
来指定 join 顺序,至少需要指定两张表,如:leading(a b)
。
对 oracle 的兼容有以下两项
支持 oracle 的 ordered
ordered
hint 用来强制使表按 from 后的表顺序去 join。
lightdb@postgres=# EXPLAIN SELECT/*+ordered*/ * FROM t3, t2, t1 WHERE t1.id = t2.id;
LOG: pg_hint_plan:
used hint:
Leading(@lt#0 ((t3@lt#0 t2@lt#0) t1@lt#0))
not used hint:
duplication hint:
error hint:
QUERY PLAN
--------------------------------------------------------------------------------
Hash Join (cost=60.85..77409.29 rows=5107600 width=24)
Hash Cond: (t2.id = t1.id)
-> Nested Loop (cost=0.00..63915.85 rows=5107600 width=16)
-> Seq Scan on t3 @"lt#0" (cost=0.00..32.60 rows=2260 width=8)
-> Materialize (cost=0.00..43.90 rows=2260 width=8)
-> Seq Scan on t2 @"lt#0" (cost=0.00..32.60 rows=2260 width=8)
-> Hash (cost=32.60..32.60 rows=2260 width=8)
-> Seq Scan on t1 @"lt#0" (cost=0.00..32.60 rows=2260 width=8)
(8 rows)
支持单表的leading
leading
用来强制指定表在 join 时作为外表去 join,如: leading(a)
。
lightdb@postgres=# EXPLAIN SELECT/*+leading(t3)*/ * FROM t3, t2, t1 WHERE t1.id = t2.id;
LOG: pg_hint_plan:
used hint:
Leading(t3@lt#0)
not used hint:
duplication hint:
error hint:
QUERY PLAN
-------------------------------------------------------------------------------------------
-
Nested Loop (cost=10000000000.16..10000064316.68 rows=5107600 width=24)
-> Seq Scan on t3 @"lt#0" (cost=0.00..32.60 rows=2260 width=8)
-> Materialize (cost=10000000000.16..10000000444.73 rows=2260 width=16)
-> Nested Loop (cost=10000000000.16..10000000433.43 rows=2260 width=16)
-> Seq Scan on t2 @"lt#0" (cost=0.00..32.60 rows=2260 width=8)
-> Index Scan using t1_pkey on t1 @"lt#0" (cost=0.15..0.18 rows=1 width=8)
Index Cond: (id = t2.id)
(7 rows)
lightdb@postgres=#
lt#0" (cost=0.15…0.18 rows=1 width=8)
Index Cond: (id = t2.id)
(7 rows)
lightdb@postgres=#
``