概述:

对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值。对于绑定变量的情况,我们知道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. SAP Web Dynpro-调试应用程序

    您可以使用ABAP工作台中的各种工具来调试源代码. 您可以使用调试器测试Web Dynpro应用程序的所有源代码. 步骤1-要启动调试器,您必须在ABAP工作台中选择一个新的调试器. 步骤2-转到实用 ...

  2. Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍

    大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第三篇了,先来回顾下前面两篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...

  3. 面试突击60:什么情况会导致 MySQL 索引失效?

    为了验证 MySQL 中哪些情况下会导致索引失效,我们可以借助 explain 执行计划来分析索引失效的具体场景. explain 使用如下,只需要在查询的 SQL 前面添加上 explain 关键字 ...

  4. 深入理解Apache Hudi异步索引机制

    在我们之前的文章中,我们讨论了多模式索引的设计,这是一种用于Lakehouse架构的无服务器和高性能索引子系统,以提高查询和写入性能.在这篇博客中,我们讨论了构建如此强大的索引所需的机制,异步索引机制 ...

  5. 暑假打工 2 个 月,让我明白了 Keepalived 高可用的三种路由方案

    暑假打工 2 个 月,让我明白了 Keepalived 高可用的三种路由方案 这是悟空的第 158 篇原创文章 原文链接:首发悟空聊架构 官网:www.passjava.cn 你好,我是悟空. 前言 ...

  6. 【docker专栏7】容器自启动与守护进程停止后容器保活

    本文为大家介绍容器自启动以及docker 守护进程挂掉或者docker升级的情况下,如何保证容器服务的正常运行.主要包含三个部分 一.守护进程开机自启 在我们安装docker的时候,介绍过启动dock ...

  7. 解气!哈工大被禁用MATLAB后,国产工业软件霸气回击

    提起哈尔滨工业大学,相信很多人都不会陌生. 它是中国顶级的C9院校之一,从1920年建校的百余年来,哈工大一直享誉"工科强校"的美称,因其在航天领域的不凡成就,更是被人们誉为&qu ...

  8. oracle删除超过N天数据脚本

    公司内做的项目是工厂内的,一般工厂内数据要求的是实时性,很久之前的数据可以自行删除处理,我们数据库用的oracle,所以就想着写一个脚本来删除,这样的话,脚本不管放在那里使用都可以达到效果 由于服务器 ...

  9. JS基础小练习

    入职薪水10K,每年涨幅入职薪水的5%,50年后工资多少? var sum = 10000; console.log(sum * (1 + 0.05 * 50)); 为抵抗洪水,战士连续作战89小时, ...

  10. Nginx 平滑升级、Nginx的一些基础配置

    # Nginx 平滑升级 # 方案一:使用Nginx服务信号进行升级 # 1.将就版本的sbin目录下可执行nginx进行备份(mv nginx nginxold) # 2.将新版本 configur ...