金仓数据库KingbaseES 绑定变量窥探机制
admin
2024-03-09 06:03:41
0

目录

窥探机制

构建例子

1、构建测试数据

2、测试窥探机制

3、窥探机制问题

对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值。

对于绑定变量的情况,我们知道Oracle 有optim_peek_user_binds 参数,控制是否启用变量窥探。KingbaseES 也有类似参数,控制是否启用变量窥探。

窥探机制

KingbaseES 采用以下判断机制,决定是否固定执行计划:

  • 前5次执行时,每次都会根据实际传入的实际绑定变量新生成执行计划进行执行,即每次都是硬解析,同时会记录这5次的执行计划;

  • 当第6次开始执行时,会生成一个通用的执行计划(generic plan),同时与前5次的执行计划进行比较,如果比较的结果是通用执行计划不比前5次的执行计划差,以后就会把这个通用的执行计划固定下来,这之后即使传入的值发生变化后,执行计划也不再变化。这就相当于Oracle打开了绑定变量窥视的功能。

  • 当然,当第6次开始执行时,如果通用的执行计划(generic plan)比前5次的某一个执行计划差,则以后则每次都重新生成执行计划,即以后永远都是硬解析了。

构建例子

1、构建测试数据

create table t1(id integer,name text);
insert into t1 select 1,repeat('a',100) from generate_series(1,1000000);
insert into t1 select 2,repeat('b',100) ;
create index ind_t1_id on t1(id);
analyze t1;
prepare t1_plan(integer) AS select count(*) from t1 where id=$1;

2、测试窥探机制

测试一:

test=# prepare t1_plan(integer) AS select * from t1 where id=$1;
PREPARE
test=#
test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = $1)
(2 rows)test=# explain execute t1_plan(2);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = $1)
(2 rows)test=# explain execute t1_plan(2);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = $1)
(2 rows)

结论:可以看到,第6次执行时,变为 id=$1,说明执行计划变成通用执行计划了。后续,即使传入的 值是 2,也不会走索引。

测试二:

test=# prepare t1_plan(integer) AS select * from t1 where id=$1;
PREPARE
test=# explain execute t1_plan(2);QUERY PLAN
----------------------------------------------------------------------Index Scan using ind_t1_id on t1  (cost=0.42..4.44 rows=1 width=105)Index Cond: (id = 2)
(2 rows)test=# explain execute t1_plan(2);QUERY PLAN
----------------------------------------------------------------------Index Scan using ind_t1_id on t1  (cost=0.42..4.44 rows=1 width=105)Index Cond: (id = 2)
(2 rows)test=# explain execute t1_plan(2);QUERY PLAN
----------------------------------------------------------------------Index Scan using ind_t1_id on t1  (cost=0.42..4.44 rows=1 width=105)Index Cond: (id = 2)
(2 rows)test=# explain execute t1_plan(2);QUERY PLAN
----------------------------------------------------------------------Index Scan using ind_t1_id on t1  (cost=0.42..4.44 rows=1 width=105)Index Cond: (id = 2)
(2 rows)test=# explain execute t1_plan(2);QUERY PLAN
----------------------------------------------------------------------Index Scan using ind_t1_id on t1  (cost=0.42..4.44 rows=1 width=105)Index Cond: (id = 2)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)test=# explain execute t1_plan(1);QUERY PLAN
--------------------------------------------------------------Seq Scan on t1  (cost=0.00..29742.01 rows=1000001 width=105)Filter: (id = 1)
(2 rows)

结论:如果第6次与前5次执行计划是不一致的,后续都不会走通用的执行计划。本例中,哪怕后续连续超过 5次 传入同一值,都不会固定执行计划。

3、窥探机制问题

与Oracle 相比,KES需要前 5 次执行绑定变量的SQL,都会窥探变量值,只有在执行计划都一致时,第6次执行时才会固定执行计划。

可以看到,这种机制相比于Oracle,出现执行计划错误的概率更低,但是还是有一定的几率。

为了解决该问题,KingbaseES提供参数,可以关闭变量窥探机制。

plan_cache_mode 参数控制是否固定执行计划(执行计划共享),还是永远进行硬解析。可以取以下三个值:

  • auto: 默认值,即根据以上的机制选择是否固定执行计划。
  • force_custom_plan: 关闭绑定变量窥视,永远进行硬解析。
  • force_generic_plan: 走通用的固定执行计划(generic plan)。比如:是否走索引是根据distinct 值的数量,而不是第一个传入的变量值。

注意:与Oracle 实例级的执行计划共享不同,KingbaseES 只支持会话级执行计划共享。

相关内容

热门资讯

原创 全... 世界风云骤变,虽然未见硝烟,但刀光剑影早已从谈判桌蔓延到了全球能源市场。2026年2月26日,在日内...
松延动力B轮融资近10亿 宁德... 3月2日,北京松延动力科技集团股份有限公司宣布完成B轮融资。本轮融资由宁德时代系产业投资平台晨道资本...
800亿发债获批!中信证券再迎... 出品|中访网 审核|李晓燕 2026年开年以来,国内证券行业龙头中信证券动作频频、亮点纷呈。公司斩获...
人工智能OPC:重塑个体创业新... 在人工智能浪潮席卷全球的当下,“一人公司”(OPC)模式正以惊人的速度崛起,成为数字经济时代个体创业...
快速涨超105%、赵蓓调研加持... 经历了2025年创新药的高光时刻后,2026年医药生物板块哪一赛道将最热成为医药产业圈和二级市场投资...
丽水启真富处基金完成备案 投资界3月2日消息,近日,浙大科创集团旗下私募基金产品丽水市启真富处创业投资基金合伙企业(有限合伙)...
ETF今日收评 | 多只油气相... 每经记者|叶峰 每经编辑|彭水萍 A股三大指数涨跌不一,沪指低开高走涨0.47%。从板块来看,油气...
比马斯克还快一步!贾跃亭的机器... 快科技3月2日消息,Faraday Future(FF)创始人、联席CEO贾跃亭宣布,公司正式启动E...
历史首次!中国石油、中国石化、... 每经记者|黄胜 每经编辑|金冥羽 记者|黄胜 编辑|金冥羽 杜恒峰 校对|陈柯名 3月2日,三大指...
揭秘“掌上工美APP”杀猪盘,...   近期,一款名为“掌上工美”的APP引发网友广泛关注与质疑,其背后的运营方为上海工美艺术品交易中心...
中航产融:“23产融06”持有... 3月2日,澎湃新闻获悉,中航产融于近期召开了“23产融06”持有人会议,会议中提到的三项议案均已通过...
春节后港股“日历效应”失灵 机... 财联社3月2日讯(编辑 胡家荣)春节假期落幕,港股市场并未如部分投资者所期迎来“春季躁动”,反而在多...
原创 2... 环比普涨难掩同比下滑,实体消费市场未有明显反弹,但存在一定程度的回暖。 注: 1.此报告基...
调整住宿税,日本京都预计增收1... 日本京都市3月1日起正式上调住宿税。住宿税新规根据酒店收费分为五档,最高税额为每人每晚1万日元(约合...
IPO动态丨本周美股预告:1家... 回顾:上周7只新股上市,其中6只为SPAC,如下: Generate Biomedicines (G...
油价、金价大涨 总台记者当地时间3月1日获悉,受中东局势持续升级影响,国际油价大幅上涨,布伦特原油价格当天一度上涨近...
伊朗封锁海峡利好油运,物流ET... 截至3月2日13点15分,上证指数涨0.41%,深证成指跌0.32%,创业板指跌0.34%。油气开采...
马斯克:你不必为AI失业焦虑 ... “10年内,人类的劳动将仅仅变成一种可选项。你可以为了享受去种菜,但绝不必为了生存而劳作。”近日,埃...
股价飙升却遭接连减持,超三成股... 本报记者 董红艳 北京报道 近年来,四川黄金股份有限公司(下称“四川黄金”,001337.SZ)接连...
东吴证券:拟收购东海证券 今日... 东吴证券3月2日早间公告,公司正在筹划通过发行A股股份的方式收购东海证券股份有限公司控制权。经公司申...