概述:

对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值。对于绑定变量的情况,我们知道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 绑定变量窥探机制的更多相关文章

  1. PostgreSQL 绑定变量窥探

    今天我们要探讨的是 custom执行计划和通用执行计划.这一技术在 Oracle中被称为绑定变量窥视.但 Kingbase中并没有这样的定义,更严格地说,Kingbase叫做custom执行计划和通用 ...

  2. KingbaseES 绑定变量与游标共享

    对于重复执行的SQL,需要使用绑定变量,避免SQL的重复解析.但是,并不是说使用了绑定变量,就一定能避免硬解析.具体可以参见:https://www.cnblogs.com/kingbase/p/16 ...

  3. ORACLE绑定变量隐式转换导致性能问题

    年后一次系统升级后,监控数据库的工具DPA发现数据库的Total Wait时间突然飙增,如下截图所示,数据库的总体等待时间对比升级前飙增了非常多 另外就是发现出现了较多的等待事件,主要有latch: ...

  4. Oracle ACS 绑定变量窥视 条件

    1. ACS简介 Oracle Database 11g提供了Adaptive Cursor Sharing (ACS)功能,以克服以往不该共享的游标被共享的可能性.ACS使用两个新指标:sensit ...

  5. Oracle 课程九之绑定变量

    课程目标 完成本课程的学习后,您应该能够: •变量绑定的目的 •父子游标 •游标共享 •绑定窥探 •SQL语句处理流程 •硬解析.软解析.软软解析 •变量绑定的应用场景   1.游标 游标可以理解为S ...

  6. Oracle面对“数据倾斜列使用绑定变量”场景的解决方案

    1.背景知识介绍 2.构造测试用例 3.场景测试 4.总结 1.背景知识介绍     我们知道,Oracle在传统的OLTP(在线事务处理)类系统中,强烈推荐使用绑定变量,这样可以有效的减少硬解析从而 ...

  7. PL/SQL 训练12--动态sql和绑定变量

    --什么是动态SQL?动态PL/SQL--动态SQL是指在运行时刻才构建执行的SQL语句--动态PL/SQL是指整个PL/SQL代码块都是动态构建,然后再编译执行 --动态SQL来可以用来干什么? - ...

  8. Oracle --获取绑定变量的值.

    SELECT * FROM DBA_HIST_SQLBIND WHERE SNAP_ID>67073 AND SNAP_ID<=67079 AND SQL_ID='3DR3410F086P ...

  9. 使用EXECUTE IMMEDIATE来生成含有绑定变量的SQL

    一个SQL,通过SPM固定它的执行计划,可以通过DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE实现.也可以通地此功能在不修改原SQL的情况下对其加HINT来固定执行计划.D ...

随机推荐

  1. Vue回炉重造之封装防刷新考试倒计时组件

    <!-- 考试倒计时组件 --> <template> <div class="time"> <p>00:{{timerCount2 ...

  2. SAP APO-部署选项

    SAP SCM Server安装提供SAP APO功能模块的所有功能. 在SAP APO的附加部署模型中,以下组件可用作SAP APO工具的一部分- OTE-在附加部署模型中,无法通过SAP SCM服 ...

  3. CompletableFuture的入门

    runAsync 和 supplyAsync runAsync接受一个Runable的实现,无返回值 CompletableFuture.runAsync(()->System.out.prin ...

  4. 华为HMS Core携手超图为三维GIS注入新动能

    6月30日,在2022(第五届)GIS软件技术大会GIS基础软件新技术板块论坛上,华为联合超图推出了基于HMS Core 3D Engine开发的高保真三维GIS插件,通过3D渲染技术助力三维GIS实 ...

  5. sql server 开启一个事务

    开启事务,回滚 /*============================================================== */ /* Date : 2020年11月18日 11 ...

  6. P2575 高手过招 题解

    题目描述 我们考虑如何把问题转换成博弈论来求解. 我们对于每一行之前都加上一个空格. 设原来这一行的空格个数是 \(C\) ,那么此时空格个数变成 \(C + 1\) . 然后按照从左到右的顺序给每一 ...

  7. P1087 FBI树 [2004普及]

    这是个正常的.很简单的分治,然后我成功地将这个题搞成了一个贼难搞的东西 还是说一下我那个非常麻烦的思路: 1. 建树 2. 后序遍历 然后就在建树的过程中死循环了,然后还一堆毛病 看了一个AC代码,该 ...

  8. 常用类-jdk8之前的日期和API

    一.System静态方法 点击查看代码 package com.Tang.StringDay01; import org.junit.Test; public class DateTimeTest { ...

  9. 【Python爬虫技巧】快速格式化请求头Request Headers

    你好,我是 @马哥python说 . 我们在写爬虫时,经常遇到这种问题,从目标网站把请求头复制下来,粘贴到爬虫代码里,需要一点一点修改格式,因为复制的是字符串string格式,请求头需要用字典dict ...

  10. 5-15 Virtual 虚拟机

    虚拟机基本使用 Virtualbox安装流程 RockyLinux VirtualBox清华大学个版本下载路径 https://mirrors.tuna.tsinghua.edu.cn/virtual ...