lightdb22.4-新增优化器提示cardinality 和ordered_predicates
admin
2024-01-30 03:35:57
0

lightdb 22.4 新增优化器提示cardinality 和ordered_predicates

lightdb 在22.4 新增了如下两个优化器提示:

  • cardinality
  • ordered hint

下面对这两个hint 进行介绍

1. cardinality hint

cardinality hint 用于强制设置表或多表查询结果的预估行数,从而影响优化器选择执行路径,hint的效果体现在对explain 中rows值的印象。

具体请看如下案例:

1.0 前置准备

lightdb@postgres=# create table t1 (key1 int , key2 int);
CREATE TABLE
lightdb@postgres=# create table t2 (key1 int , key2 int);
CREATE TABLE

1.1 影响join算法选择

通过使用cardinality设置t1表预估行数为10,导致走了hashjoin:


lightdb@postgres=# explain select * from t1, t2 where t1.key1 = t2.key1;QUERY PLAN                            
------------------------------------------------------------------Merge Join  (cost=317.01..711.38 rows=25538 width=16)Merge Cond: (t1.key1 = t2.key1)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: t1.key1->  Seq Scan on t1  (cost=0.00..32.60 rows=2260 width=8)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: t2.key1->  Seq Scan on t2  (cost=0.00..32.60 rows=2260 width=8)
(8 rows)lightdb@postgres=# explain select /*+cardinality(t1 10)*/* from t1, t2 where t1.key1 = t2.key1;QUERY PLAN                               
------------------------------------------------------------------------Hash Join  (cost=32.73..74.93 rows=113 width=16)Hash Cond: (t2.key1 = t1.key1)->  Seq Scan on t2 @"lt#0"  (cost=0.00..32.60 rows=2260 width=8)->  Hash  (cost=32.60..32.60 rows=10 width=8)->  Seq Scan on t1 @"lt#0"  (cost=0.00..32.60 rows=10 width=8)
(5 rows)lightdb@postgres=# 

1.2 影响内外表选择

对应hashjoin,可以通过把rows 设小,可以强制把设置的表作为内表构建hash表。

lightdb@postgres=# explain select /*+cardinality(t1 20) cardinality(t2 20)*/* from t1, t2 where t1.key1 = t2.key1;QUERY PLAN                               
------------------------------------------------------------------------Hash Join  (cost=32.85..65.57 rows=2 width=16)Hash Cond: (t1.key1 = t2.key1)->  Seq Scan on t1 @"lt#0"  (cost=0.00..32.60 rows=20 width=8)->  Hash  (cost=32.60..32.60 rows=20 width=8)->  Seq Scan on t2 @"lt#0"  (cost=0.00..32.60 rows=20 width=8)
(5 rows)lightdb@postgres=# explain select /*+cardinality(t1 10) cardinality(t2 20)*/* from t1, t2 where t1.key1 = t2.key1;QUERY PLAN                               
------------------------------------------------------------------------Hash Join  (cost=32.73..65.41 rows=1 width=16)Hash Cond: (t2.key1 = t1.key1)->  Seq Scan on t2 @"lt#0"  (cost=0.00..32.60 rows=20 width=8)->  Hash  (cost=32.60..32.60 rows=10 width=8)->  Seq Scan on t1 @"lt#0"  (cost=0.00..32.60 rows=10 width=8)
(5 rows)lightdb@postgres=# explain select /*+cardinality(t1 20) cardinality(t2 10)*/* from t1, t2 where t1.key1 = t2.key1;QUERY PLAN                               
------------------------------------------------------------------------Hash Join  (cost=32.73..65.41 rows=1 width=16)Hash Cond: (t1.key1 = t2.key1)->  Seq Scan on t1 @"lt#0"  (cost=0.00..32.60 rows=20 width=8)->  Hash  (cost=32.60..32.60 rows=10 width=8)->  Seq Scan on t2 @"lt#0"  (cost=0.00..32.60 rows=10 width=8)
(5 rows)lightdb@postgres=# 

1.3 影响子查询

lightdb@postgres=# explain select t1.key1 from t1, (select distinct * from t2 ) x where t1.key1 = x.key1 and x.key2>10;QUERY PLAN                                  
-----------------------------------------------------------------------------Hash Join  (cost=49.23..174.72 rows=2509 width=4)Hash Cond: (t1.key1 = x.key1)->  Seq Scan on t1  (cost=0.00..32.60 rows=2260 width=4)->  Hash  (cost=46.45..46.45 rows=222 width=4)->  Subquery Scan on x  (cost=42.02..46.45 rows=222 width=4)->  HashAggregate  (cost=42.02..44.23 rows=222 width=8)Group Key: t2.key1, t2.key2->  Seq Scan on t2  (cost=0.00..38.25 rows=753 width=8)Filter: (key2 > 10)
(9 rows)lightdb@postgres=# explain select /*+cardinality(x 100)*/t1.key1 from t1, (select distinct * from t2 ) x where t1.key1 = x.key1 and x.key2>10;QUERY PLAN                              -----------------------------------------------------------------------------
--------Hash Join  (cost=47.70..125.50 rows=1130 width=4)Hash Cond: (t1.key1 = x.key1)->  Seq Scan on t1 @"lt#0"  (cost=0.00..32.60 rows=2260 width=4)->  Hash  (cost=46.45..46.45 rows=100 width=4)->  Subquery Scan on x @"lt#0"  (cost=42.02..46.45 rows=100 width=4)->  HashAggregate  (cost=42.02..44.23 rows=222 width=8)Group Key: t2.key1, t2.key2->  Seq Scan on t2 @"lt#1"  (cost=0.00..38.25 rows=753 w
idth=8)Filter: (key2 > 10)
(9 rows)lightdb@postgres=# 

1.4 影响多表

lightdb@postgres=# explain select * from t1 ,t2 ,t1 a where t1.key1=t2.key1 and t2.key1=a.key1;QUERY PLAN                                 -----------------------------------------------------------------------------
-Merge Join  (cost=475.52..5209.87 rows=288579 width=24)Merge Cond: (a.key1 = t1.key1)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: a.key1->  Seq Scan on t1 a  (cost=0.00..32.60 rows=2260 width=8)->  Materialize  (cost=317.01..775.23 rows=25538 width=16)->  Merge Join  (cost=317.01..711.38 rows=25538 width=16)Merge Cond: (t1.key1 = t2.key1)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: t1.key1->  Seq Scan on t1  (cost=0.00..32.60 rows=2260 width=8)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: t2.key1->  Seq Scan on t2  (cost=0.00..32.60 rows=2260 width=8)
(14 rows)lightdb@postgres=# explain select /*+cardinality(t1 t2 100)*/* from t1 ,t2 ,t1 a where t1.key1=t2.key1 and t2.key1=a.key1;QUERY PLAN                             -----------------------------------------------------------------------------
---------Hash Join  (cost=712.63..790.43 rows=1130 width=24)Hash Cond: (a.key1 = t1.key1)->  Seq Scan on t1 a @"lt#0"  (cost=0.00..32.60 rows=2260 width=8)->  Hash  (cost=711.38..711.38 rows=100 width=16)->  Merge Join  (cost=317.01..711.38 rows=100 width=16)Merge Cond: (t1.key1 = t2.key1)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: t1.key1->  Seq Scan on t1 @"lt#0"  (cost=0.00..32.60 rows=2260 
width=8)->  Sort  (cost=158.51..164.16 rows=2260 width=8)Sort Key: t2.key1->  Seq Scan on t2 @"lt#0"  (cost=0.00..32.60 rows=2260 
width=8)
(12 rows)lightdb@postgres=# 

note

cardinality hint是rows hint 的别名,在22.4 我们对rows hint 进行了扩展,支持对单表进行设置。

2. ordered_predicates hint

ordered_predicates 用于强制优化器保留约束的顺序,对索引条件无效, 不考虑连接条件。目前具有如下限制:

  • 对于涉及等价推导的约束不起效,包括实际参与推导,和推导参数的约束。

具体案例如下:

2.0 前置准备

chuhx@postgres=# create table test1 (key1 int, key2 int, key3 int);
CREATE TABLE
chuhx@postgres=# create table test2 (key1 int, key2 int, key3 int);
CREATE TABLE
chuhx@postgres=# 

2.1 对于where 或on或having后约束 不组合

where

lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 where mod(key2, 10) = 2 and key1 = 1;QUERY PLAN                   
------------------------------------------------Seq Scan on test1Filter: ((key1 = 1) AND (mod(key2, 10) = 2))
(2 rows)lightdb@postgres=# EXPLAIN (COSTS false) select/*+ordered_predicates*/ * from test1 where mod(key2, 10) = 2 and key1 = 1;  QUERY PLAN                   
------------------------------------------------Seq Scan on test1 @"lt#0"Filter: ((mod(key2, 10) = 2) AND (key1 = 1))
(2 rows)lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 where mod(key2, 10) = 2 and key1 > 1;QUERY PLAN                   
------------------------------------------------Seq Scan on test1Filter: ((key1 > 1) AND (mod(key2, 10) = 2))
(2 rows)lightdb@postgres=# EXPLAIN (COSTS false) select/*+ordered_predicates*/ * from test1 where mod(key2, 10) = 2 and key1 > 1;QUERY PLAN                   
------------------------------------------------Seq Scan on test1 @"lt#0"Filter: ((mod(key2, 10) = 2) AND (key1 > 1))
(2 rows)

on

lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 a join test2 b on a.key1=b.key1 and mod(a.key2, 10) = 2 and  a.key3 = 10; QUERY PLAN                          
-------------------------------------------------------------Hash JoinHash Cond: (b.key1 = a.key1)->  Seq Scan on test2 b->  Hash->  Seq Scan on test1 aFilter: ((key3 = 10) AND (mod(key2, 10) = 2))
(6 rows)lightdb@postgres=# EXPLAIN (COSTS false) select/*+ordered_predicates*/ * from test1 a join test2 b on a.key1=b.key1 and mod(a.key2, 10) = 2 and  a.key3 = 10; QUERY PLAN                          
-------------------------------------------------------------Hash JoinHash Cond: (b.key1 = a.key1)->  Seq Scan on test2 b @"lt#0"->  Hash->  Seq Scan on test1 a @"lt#0"Filter: ((mod(key2, 10) = 2) AND (key3 = 10))
(6 rows)

having

lightdb@postgres=# EXPLAIN (COSTS false) select key1 from test1 group by key1, key2 having mod(key2, 10) = 2 and key1 = 1;QUERY PLAN                         
------------------------------------------------------------GroupGroup Key: key1, key2->  SortSort Key: key2->  Seq Scan on test1Filter: ((key1 = 1) AND (mod(key2, 10) = 2))
(6 rows)lightdb@postgres=# EXPLAIN (COSTS false) select/*+ordered_predicates*/ key1 from test1 group by key1, key2 having mod(key2, 10) = 2 and key1 = 1;QUERY PLAN                         
------------------------------------------------------------GroupGroup Key: key1, key2->  SortSort Key: key2->  Seq Scan on test1 @"lt#0"Filter: ((mod(key2, 10) = 2) AND (key1 = 1))
(6 rows)

2.2 on 和where 结合(无等价推导, having 类同where,不再举例)

lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 a join test2 b on a.key1=b.key1 and mod(a.key2, 10) = 2 where mod(b.key2, 10) = 2 and a.key3 = 10; QUERY PLAN                       
-------------------------------------------------------Nested LoopJoin Filter: (a.key1 = b.key1)->  Seq Scan on test1 aFilter: ((key3 = 10) AND (mod(key2, 10) = 2))->  Seq Scan on test2 bFilter: (mod(key2, 10) = 2)
(6 rows)lightdb@postgres=# EXPLAIN (COSTS false) select/*+ordered_predicates*/ * from test1 a join test2 b on a.key1=b.key1 and mod(a.key2, 10) = 2 where mod(b.key2, 10) = 2 and a.key3 = 10; QUERY PLAN                       
-------------------------------------------------------Nested LoopJoin Filter: (a.key1 = b.key1)->  Seq Scan on test1 a @"lt#0"Filter: ((mod(key2, 10) = 2) AND (key3 = 10))->  Seq Scan on test2 b @"lt#0"Filter: (mod(key2, 10) = 2)
(6 rows)

2.3 不起效情况

有等价类推导a.key2=b.key2 && b.key2 = 1 导致 b 表上的 ((key2 = 1) AND (mod(key2, 10) = 2)) 不能保持sql 中定义顺序。

lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 a left join test2 b on a.key1=b.key1 and a.key2=b.key2 where mod(b.key2, 10) = 2 and b.key2 = 1; 
e                      QUERY PLAN                      
y2 where mod(b.key2, 10) = 2 and b.key2 = 1; 
------------------------------------------------------Nested LoopJoin Filter: (a.key1 = b.key1)->  Seq Scan on test2 bFilter: ((key2 = 1) AND (mod(key2, 10) = 2))->  Seq Scan on test1 aFilter: (key2 = 1)
(6 rows)lightdb@postgres=# EXPLAIN (COSTS false) select/*+ordered_predicates*/ * from test1 a left join test2 b on a.key1=b.key1 and a.key2=b.key2 where mod(b.key2, 10) = 2 and b.key2 = 1; QUERY PLAN                      
------------------------------------------------------Nested LoopJoin Filter: (a.key1 = b.key1)->  Seq Scan on test2 b @"lt#0"Filter: ((key2 = 1) AND (mod(key2, 10) = 2))->  Seq Scan on test1 a @"lt#0"Filter: (key2 = 1)
(6 rows)

有等价类推导a.key2=b.key2和a.key2 = 1 导致 a 表上((key2 = 1) AND (mod(key2, 10) = 2)) 不能保留sql中顺序。

这边单独说明是因为在代码内部与上述不起效的原理不同(由于外连接)。

lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 a left join test2 b on a.key1=b.key1 and a.key2=b.key2 where mod(a.key2, 10) = 2 and a.key2 = 1;
y2 where mod(a.key2, 10) = 2 and a.key2 = 1;QUERY PLAN                        
----------------------------------------------------------Nested Loop Left JoinJoin Filter: ((a.key2 = b.key2) AND (a.key1 = b.key1))->  Seq Scan on test1 aFilter: ((key2 = 1) AND (mod(key2, 10) = 2))->  Seq Scan on test2 bFilter: (key2 = 1)
(6 rows)lightdb@postgres=# EXPLAIN (COSTS false) select /*+ordered_predicates*/* from test1 a left join test2 b on a.key1=b.key1 and a.key2=b.key2 where mod(a.key2, 10) = 2 and a.key2 = 1;QUERY PLAN                        
----------------------------------------------------------Nested Loop Left JoinJoin Filter: ((a.key2 = b.key2) AND (a.key1 = b.key1))->  Seq Scan on test1 a @"lt#0"Filter: ((key2 = 1) AND (mod(key2, 10) = 2))->  Seq Scan on test2 b @"lt#0"Filter: (key2 = 1)
(6 rows)

相关内容

热门资讯

2026年1-7月债务融资工具... 来源:21世纪经济报道 来源:中国银行间市场交易商协会 表1:中长期承销情况统计 表2:服务企业...
代工赚薄利,风险工厂背,优思益... 本报(chinatimes.net.cn)记者王瑜 于娜 北京报道 作为国内营养保健食品CDMO龙头...
原创 智... 雷达财经出品 文|周慧 编|孟帅 以后买Token,可以去电商平台了! 9月2日,国产大模型厂商智谱...
白癜风医生林华:早期白癜风能治... 很多患者在确诊早期白癜风后都会问同一个问题:早期白癜风能治好吗?其实,白癜风虽然是一种慢性皮肤病,治...
孙明达履新济南城投集团党委书记... 9月2日,据“济南城投”微信公众号消息,济高控股集团与济南城投集团战略合作协议签约活动举行,孙明达以...
报名启动!2026中国医药决策... 企业竞争力的每一点积累和提升,都起始于决策者们的判断与掌舵。靶点和技术路线选择、产品立项与临床推进,...
月之暗面秘密递表港交所,正式启... 9月2日,据《晚点LatePost》消息,月之暗面(Kimi)已于本周以保密形式向港交所递交A1文件...
20家白酒企业半年考:“量价利... 仍处于深度调整期的白酒行业交出了一份“量价利”齐跌的“中考”成绩单。 澎湃新闻记者梳理了20家白酒上...
新信号出现了!市场快速拉升,0... 水岸 9月2日的市场,指数在探底后出现盘中反转,又一次上演了“跌有支撑,韧性十足”的戏码。 个股的...
原创 宇... 9月2日,A股"人形机器人第一股"宇树科技(688836.SH)在上市后的第11个交易日盘中跌破55...
港股探底回升 恒指微跌0.07... 今日(9月2日),港股市场早盘一路走低,但尾市强势回升,最终恒生指数仅微幅下跌。 截至收盘,恒生指数...
广州典当行到底能干什么?普通人... 很多生活在广州的朋友,遇到资金周转缺口的时候,第一反应就是网贷、信用卡套现,很少会认真去了解典当这个...
刚刚宣布!A50,重大调整 A50指数即将迎来重大调整。 今日盘后,富时罗素(FTSE Russell)宣布对富时中国指数系列的...
兴证全球三位百亿基金经理对科技... 来源:市值风云 兴证全球基金在持有人盈利占比上遥遥领先。 作者 | Los 编辑 | 小白 盈...
星宇股份董事长周晓萍对解约应届... 星宇股份董事长周晓萍就应届生解约致歉,称后续将整改,保障劳动者合法权益 据澎湃新闻,9月2日,常州...
中保中报⑩上市险企银保增速分化... 从萌芽起步到高速扩张,再到规范化发展,银保渠道正在从“规模扩张”向“价值提升”转变。 近日,随着上市...
纽约时报广场被刺身亡银行副总裁... 当地时间8月31日下午4时26分左右,一名女子手持双刀,在纽约市曼哈顿时报广场核心区域行凶,导致一名...
人气急转直下,10只热门股创历... 9月2日,A股缩量盘整,市场中位数-0.94%,盘面较为沉寂,3900股下跌,亏钱效应较高。全天三大...
支付宝数字能源携手水燃机构 发... 9月2日,2026支付宝生活缴费行业生态论坛举办。活动现场,支付宝数字能源正式推出生态联营计划,首批...
华安基金:中报验证光通信高景气 来源:新浪基金 行情回顾及主要观点: 上周A股市场整体呈现分化趋势:沪深300跌0.21%,中证50...