KingbaseES 绑定变量窥探机制
概述:
对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值。对于绑定变量的情况,我们知道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)
注意:与Oracle 实例级的执行计划共享不同,KingbaseES 只支持会话级执行计划共享。
KingbaseES 绑定变量窥探机制的更多相关文章
- PostgreSQL 绑定变量窥探
今天我们要探讨的是 custom执行计划和通用执行计划.这一技术在 Oracle中被称为绑定变量窥视.但 Kingbase中并没有这样的定义,更严格地说,Kingbase叫做custom执行计划和通用 ...
- KingbaseES 绑定变量与游标共享
对于重复执行的SQL,需要使用绑定变量,避免SQL的重复解析.但是,并不是说使用了绑定变量,就一定能避免硬解析.具体可以参见:https://www.cnblogs.com/kingbase/p/16 ...
- ORACLE绑定变量隐式转换导致性能问题
年后一次系统升级后,监控数据库的工具DPA发现数据库的Total Wait时间突然飙增,如下截图所示,数据库的总体等待时间对比升级前飙增了非常多 另外就是发现出现了较多的等待事件,主要有latch: ...
- Oracle ACS 绑定变量窥视 条件
1. ACS简介 Oracle Database 11g提供了Adaptive Cursor Sharing (ACS)功能,以克服以往不该共享的游标被共享的可能性.ACS使用两个新指标:sensit ...
- Oracle 课程九之绑定变量
课程目标 完成本课程的学习后,您应该能够: •变量绑定的目的 •父子游标 •游标共享 •绑定窥探 •SQL语句处理流程 •硬解析.软解析.软软解析 •变量绑定的应用场景 1.游标 游标可以理解为S ...
- Oracle面对“数据倾斜列使用绑定变量”场景的解决方案
1.背景知识介绍 2.构造测试用例 3.场景测试 4.总结 1.背景知识介绍 我们知道,Oracle在传统的OLTP(在线事务处理)类系统中,强烈推荐使用绑定变量,这样可以有效的减少硬解析从而 ...
- PL/SQL 训练12--动态sql和绑定变量
--什么是动态SQL?动态PL/SQL--动态SQL是指在运行时刻才构建执行的SQL语句--动态PL/SQL是指整个PL/SQL代码块都是动态构建,然后再编译执行 --动态SQL来可以用来干什么? - ...
- Oracle --获取绑定变量的值.
SELECT * FROM DBA_HIST_SQLBIND WHERE SNAP_ID>67073 AND SNAP_ID<=67079 AND SQL_ID='3DR3410F086P ...
- 使用EXECUTE IMMEDIATE来生成含有绑定变量的SQL
一个SQL,通过SPM固定它的执行计划,可以通过DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE实现.也可以通地此功能在不修改原SQL的情况下对其加HINT来固定执行计划.D ...
随机推荐
- MySQL根据表前缀批量修改、删除表
注意:请先调试好,以及做好备份,再执行操作. 批量修改表 批量给前缀为 xushanxiang_content_ 的表增加一个 username 的字段: SELECT CONCAT('ALTER T ...
- UiPath参数介绍和使用
一.参数介绍 用于将数据从一个项目传递到另一个项目.在全局意义上,它们类似于变量,因为它们动态地存储数据并传递给它.变量在活动之间传递数据,而参数在自动化之间传递数据.因此,它们使你能够一次又一次地重 ...
- 数仓的字符截取三胞胎:substrb、substr、substring
摘要:下面就来给大家介绍这三个函数在字符截取时的一些用法与区别. 本文分享自华为云社区<GaussDB(DWS)中的字符截取三胞胎>,作者:我站在北方的天空下 . 在GaussDB(DWS ...
- Vue动态组件的实践与原理探究
我司有一个工作台搭建产品,允许通过拖拽小部件的方式来搭建一个工作台页面,平台内置了一些常用小部件,另外也允许自行开发小部件上传使用,本文会从实践的角度来介绍其实现原理. ps.本文项目使用Vue CL ...
- Linux 磁盘挂载和swap空间管理
挂载:把指定的设备和根下面的某个文件夹建立关联 卸载:解除两者关系的过程 挂载文件系统:mount 格式:mount device mountpoint --- mount 设备名 挂载点 mount ...
- idea 内置tomcat jersey 跨服务器 上传文件报400错误
报错内容 com.sun.jersey.api.client.UniformInterfaceException: PUT http://.jpg returned a response status ...
- vue3代码编写
vue3代码编写 团队内的vue3已经升级一年,在这一年中vue也在不停的更新,为了最大化组合式api带来的优势,便需要合理规范代码的编写方式- 1.从vue2到vue3 vue2组件采用配置式API ...
- 部署yum仓库
YUM介绍 YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器. 基于RPM包管理,能够从指定的 ...
- Centos7中配置NIS:用户账号管理
NIS:网络信息服务 Linux系统中用户按地域分两类:本地用户,远程用户(NIS.LDAP.AD)模式:C/S模式 ypbind是定义NIS服务器的客户端进程,一旦确定了服务器位置,客户端绑定到了服 ...
- input 输入框背景色设置为透明