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 ...
随机推荐
- node线上项目连接mysql出现 504 Gateway Time-Out
var connection = mysql.createConnection({host : 'localhost',user : 'root',password : '123456',port: ...
- 【Nginx】Windows平台下配置Nginx服务实现负载均衡
前言:废话不多说了,直接上步骤. 系统环境:win10 测试用的开发环境和服务类型:VS2022 + DotNet 6 + WebApi 1.本地先创建一个webapi项目,用于测试使用. 2.新建一 ...
- python各种BUG报错解决
报错1 python学习交流群:660193417### Could not build atari-py: Command '['cmake', '..']' returned non-zero e ...
- C#实现一个万物皆可排序的队列
需求 产品中需要向不同的客户推送数据,原来的实现是每条数据产生后就立即向客户推送数据,走的的是HTTP协议.因为每条数据都比较小,而数据生成的频次也比较高,这就会频繁的建立HTTP连接,而且每次HTT ...
- 【python基础】第19回 多层,有参装饰器 递归 二分法
本章内容概要 1. 多层装饰器 2. 有参装饰器 3. 递归函数 4. 算法(二分法) 本章内容详解 1. 多层装饰器 1.1 什么是多层装饰器 多层装饰器是从下往上依次执行,需要注意的是,被装饰的函 ...
- JUC源码学习笔记2——AQS共享和Semaphore,CountDownLatch
本文主要讲述AQS的共享模式,共享和独占具有类似的套路,所以如果你不清楚AQS的独占的话,可以看我的<JUC源码学习笔记1> 主要参考内容有<Java并发编程的艺术>,< ...
- 06 app分享功能
通过某一个点击事件触发confirm弹窗 确定后正式进行分享功能处理 这是一个封装好的分享功能插件 https://ext.dcloud.net.cn/plugin?id=4860 如果自己写的话会很 ...
- 管正雄:基于预训练模型、智能运维的QA生成算法落地
分享嘉宾:管正雄 阿里云 高级算法工程师 出品平台:DataFunTalk 导读:面对海量的用户问题,有限的支持人员该如何高效服务好用户?智能QA生成模型给业务带来的提效以及如何高效地构建算法服务,为 ...
- Dubbo源码(三) - 服务导出(生产者)
前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 在了解了Dubbo SPI后,我们来了解下Dubbo服务导出的过程. Dubbo的配置是通过Du ...
- File类创建删除功能的方法和File类遍历目录功能
File类创建删除功能的方法 public boolean createNewFile();当且仅当具有该名称的文件尚不存在的时候,创建一个新的空文件 public boolean delete(); ...