概述:

对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值。对于绑定变量的情况,我们知道Oracle 有 _optim_peek_user_binds 参数,控制是否启用变量窥探。KingbaseES 也有类似参数,控制是否启用变量窥探。

窥探机制

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

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

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

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

构建例子

1、构建测试数据

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

2、测试窥探机制

测试一:

  1. test=# prepare t1_plan(integer) AS select * from t1 where id=$1;
  2. PREPARE
  3. test=#
  4. test=# explain execute t1_plan(1);
  5. QUERY PLAN
  6. --------------------------------------------------------------
  7. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  8. Filter: (id = 1)
  9. (2 rows)
  10.  
  11. test=# explain execute t1_plan(1);
  12. QUERY PLAN
  13. --------------------------------------------------------------
  14. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  15. Filter: (id = 1)
  16. (2 rows)
  17.  
  18. test=# explain execute t1_plan(1);
  19. QUERY PLAN
  20. --------------------------------------------------------------
  21. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  22. Filter: (id = 1)
  23. (2 rows)
  24.  
  25. test=# explain execute t1_plan(1);
  26. QUERY PLAN
  27. --------------------------------------------------------------
  28. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  29. Filter: (id = 1)
  30. (2 rows)
  31.  
  32. test=# explain execute t1_plan(1);
  33. QUERY PLAN
  34. --------------------------------------------------------------
  35. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  36. Filter: (id = 1)
  37. (2 rows)
  38.  
  39. test=# explain execute t1_plan(1);
  40. QUERY PLAN
  41. --------------------------------------------------------------
  42. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  43. Filter: (id = $1)
  44. (2 rows)
  45.  
  46. test=# explain execute t1_plan(2);
  47. QUERY PLAN
  48. --------------------------------------------------------------
  49. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  50. Filter: (id = $1)
  51. (2 rows)
  52.  
  53. test=# explain execute t1_plan(2);
  54. QUERY PLAN
  55. --------------------------------------------------------------
  56. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  57. Filter: (id = $1)
  58. (2 rows)

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

测试二:

  1. test=# prepare t1_plan(integer) AS select * from t1 where id=$1;
  2. PREPARE
  3. test=# explain execute t1_plan(2);
  4. QUERY PLAN
  5. ----------------------------------------------------------------------
  6. Index Scan using ind_t1_id on t1 (cost=0.42..4.44 rows=1 width=105)
  7. Index Cond: (id = 2)
  8. (2 rows)
  9.  
  10. test=# explain execute t1_plan(2);
  11. QUERY PLAN
  12. ----------------------------------------------------------------------
  13. Index Scan using ind_t1_id on t1 (cost=0.42..4.44 rows=1 width=105)
  14. Index Cond: (id = 2)
  15. (2 rows)
  16.  
  17. test=# explain execute t1_plan(2);
  18. QUERY PLAN
  19. ----------------------------------------------------------------------
  20. Index Scan using ind_t1_id on t1 (cost=0.42..4.44 rows=1 width=105)
  21. Index Cond: (id = 2)
  22. (2 rows)
  23.  
  24. test=# explain execute t1_plan(2);
  25. QUERY PLAN
  26. ----------------------------------------------------------------------
  27. Index Scan using ind_t1_id on t1 (cost=0.42..4.44 rows=1 width=105)
  28. Index Cond: (id = 2)
  29. (2 rows)
  30.  
  31. test=# explain execute t1_plan(2);
  32. QUERY PLAN
  33. ----------------------------------------------------------------------
  34. Index Scan using ind_t1_id on t1 (cost=0.42..4.44 rows=1 width=105)
  35. Index Cond: (id = 2)
  36. (2 rows)
  37.  
  38. test=# explain execute t1_plan(1);
  39. QUERY PLAN
  40. --------------------------------------------------------------
  41. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  42. Filter: (id = 1)
  43. (2 rows)
  44.  
  45. test=# explain execute t1_plan(1);
  46. QUERY PLAN
  47. --------------------------------------------------------------
  48. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  49. Filter: (id = 1)
  50. (2 rows)
  51.  
  52. test=# explain execute t1_plan(1);
  53. QUERY PLAN
  54. --------------------------------------------------------------
  55. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  56. Filter: (id = 1)
  57. (2 rows)
  58.  
  59. test=# explain execute t1_plan(1);
  60. QUERY PLAN
  61. --------------------------------------------------------------
  62. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  63. Filter: (id = 1)
  64. (2 rows)
  65.  
  66. test=# explain execute t1_plan(1);
  67. QUERY PLAN
  68. --------------------------------------------------------------
  69. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  70. Filter: (id = 1)
  71. (2 rows)
  72.  
  73. test=# explain execute t1_plan(1);
  74. QUERY PLAN
  75. --------------------------------------------------------------
  76. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  77. Filter: (id = 1)
  78. (2 rows)
  79.  
  80. test=# explain execute t1_plan(1);
  81. QUERY PLAN
  82. --------------------------------------------------------------
  83. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  84. Filter: (id = 1)
  85. (2 rows)
  86.  
  87. test=# explain execute t1_plan(1);
  88. QUERY PLAN
  89. --------------------------------------------------------------
  90. Seq Scan on t1 (cost=0.00..29742.01 rows=1000001 width=105)
  91. Filter: (id = 1)
  92. (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. Win 系统下使用gnvm操作node版本

    下载 gnvm官方网址 有好几种安装方式,我这里使用的是百度网盘下载. 安装 下载完成将gnvm.exe文件放到node的安装根目录下,如果你不知道安装目录在哪?可以使用命令: where node ...

  2. go int64传到前端导致溢出问题排查

    简介 ​ 开周会的时候一位同事分享了一个踩坑经验,说在go里面还好好的int64类型,到前端就变得奇奇怪怪了,和原来不一样了.正好我对前端javascript有一点点了解,然后连夜写了点代码探索了一下 ...

  3. MongoDB 的安装和基本操作

    MongoDB 的安装 使用 docker 安装 下载镜像: docker pull mongo:4.4.8(推荐,下载指定版本) docker pull mongo:latest (默认下载最新版本 ...

  4. Nginx越界读取缓存漏洞 CVE-2017-7529

    1.漏洞描述 Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件.缓存的部分存储在文件中,每个缓存文件包括"文件头"+"HTTP返回包头" ...

  5. 记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究

    开心一刻 一天在路边看到一个街头采访 记者:请问,假如你儿子娶媳妇,给多少彩礼合适呢 大爷:一百万吧,再给一套房,一辆车 大爷沉思一下,继续说到:如果有能力的话再给老丈人配一辆车,毕竟他把女儿养这么大 ...

  6. 常用源&配置

    ubuntu16.04 阿里 cp /etc/apt/sources.list /etc/apt/sources.list.orgin && \ echo "\ deb ht ...

  7. supervisor 按天备份日志

    参考使用 logrotate 配置 supervisor 进行日志管理按天备份 supervisor默认的日志备份策略是按大小备份,经常不知道去哪个文件查日志的烦恼.本文通过设置 logrotate ...

  8. Solution -「Luogu 4135」作诗

    写在前面 & 前置芝士   好像是好久没有打理 blog 了.感觉上学期是有点颓.嘶,初三了好好冲一次吧.   那么回到这道题目.你会分块就能看懂. 题目大意   先挂个来自洛谷的 link. ...

  9. OptaPlanner 发展方向与问题

    ​ 最近一段时间,因为忙于[易排(EasyPlan)规划平台]的设计与开发工作,平台的一些功能设计,需要对OptaPlanner的各种特性作更深入的研究与应用.慢慢发现,OptaPlanner进入8. ...

  10. Nginx搭建简易文件服务器

    Nginx搭建简易文件服务器 1.安装nginx,此处略过 2.修改nginx配置文件 详细如下 # 此处为部分文件是否有权限,使用root,则不会出现403权限问题 user root; worke ...