Oracle绑定变量分级(Bind Graduation)



绑定变量分级(Bind Graduation)是指Oracle在PL/SQL代码中会根据文本型绑定变量的定义长度而将这些文本型绑定变量分为四个等级,如下所示:

l 定义长度小于等于32字节(Byte)的文本型绑定变量被分在第一个等级,Oracle为其分配32字节的内存空间。

l 定义长度在[33,128]字节之间的被分在第二个等级,Oracle为其分配128字节的内存空间。

l 定义长度在[129,2000]字节之间的文本型绑定变量被分在第三个等级,Oracle为其分配2000字节的内存空间。

l 定义长度在2000字节以上被分在第四个等级,Oracle为此等级的文本型绑定变量分配的内存空间大小取决于对应文本型绑定变量所传入的实际绑定变量值的大小。如果实际传入的绑定变量值小于或等于2000字节,那么Oracle会为其分配2000字节的内存空间。如果实际传入的绑定变量值大于2000字节,那么Oracle会为其分配4000字节的内存空间。

需要注意的是,绑定变量分级仅适用于文本型的绑定变量,Oracle不会对数值(NUMBER)型的绑定变量做绑定变量分级。Oracle数据库中数值型的变量最大只能占用22字节,所以对于数值型的绑定变量而言,Oracle统一为其分配了22字节的内存空间。

如果在PL/SQL代码中使用了文本型绑定变量,只要其SQL文本中文本型绑定变量的定义长度发生了变化,那么Oracle为这些绑定变量所分配的内存空间的大小也可能会随之发生变化,而一旦Oracle为这些绑定变量所分配的内存空间的大小发生了变化,那么该SQL之前存储在Child Cursor中的解析树和执行计划就不能被重用了。其原因是Child Cursor中除了会存储目标SQL的解析树和执行计划之外,还会存储该SQL所使用的绑定变量的类型和长度,这意味着即使该SQL的SQL文本没有发生任何改变,只要其SQL文本中文本型绑定变量的定义长度发生了变化,那么该SQL再次执行时就可能还是做硬解析(新生成一个子游标)。

下面给出一个示例(数据库版本为11.2.0.3):

建表T_BG_20170610_LHR,并给出5个PL/SQL代码:

CREATE TABLE T_BG_20170610_LHR(N NUMBER(10),V VARCHAR2(3000));

--SQL_TEXT1:硬解析

DECLARE

N NUMBER(10) :=1;--分配22字节的内存空间

  V VARCHAR2(32) :='XIAOMAIMIAO1';--分配32字节的内存空间

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)' USING N, V;

COMMIT;

END;

/

--SQL_TEXT2:硬解析

DECLARE

N NUMBER(10) :=2;--分配22字节的内存空间

  V VARCHAR2(33) :='XIAOMAIMIAO2';--分配128字节的内存空间

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)' USING N, V;

COMMIT;

END;

/

--SQL_TEXT3:硬解析

DECLARE

N NUMBER(10) :=3;--分配22字节的内存空间

  V VARCHAR2(129) :='XIAOMAIMIAO3';--分配2000字节的内存空间

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)' USING N, V;

COMMIT;

END;

/

--SQL_TEXT4:软解析

DECLARE

N NUMBER(10) :=4;--分配22字节的内存空间

  V VARCHAR2(2001) :='XIAOMAIMIAO4';--分配2000字节的内存空间

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)' USING N, V;

COMMIT;

END;

/

--SQL_TEXT5:软解析

DECLARE

N NUMBER(10) :=5;--分配22字节的内存空间

  V VARCHAR2(32767) :='XIAOMAIMIAO5';--分配2000字节的内存空间

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)' USING N, V;

COMMIT;

END;

/

--SQL_TEXT6: 硬解析

DECLARE

N NUMBER(10) :=6;  --分配22字节的内存空间

  V VARCHAR2(32767) :=RPAD('XIAOMAIMIAO6',2002,'8');  --字符串长度为2002,分配4000字节的内存空间

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)' USING N, V;

COMMIT;

END;

/

执行上述建表语句和PL/SQL代码,查看结果:

LHR@orclasm > col v format a13

LHR@orclasm > select * from T_BG_20170610_LHR T WHERE T.N<=5;

N V

---------- -------------

1 XIAOMAIMIAO1

2 XIAOMAIMIAO2

3 XIAOMAIMIAO3

4 XIAOMAIMIAO4

5 XIAOMAIMIAO5

LHR@orclasm > SELECT T.N,LENGTH(T.V) FROM T_BG_20170610_LHR T;

N LENGTH(T.V)

---------- -----------

1          12

2          12

3          12

4          12

5          12

6        2002

一旦Oracle为这些文本型绑定变量所分配的内存空间的大小发生了变化,那么该SQL之前存储在Child Cursor中的解析树和执行计划就不能被重用了。所以这里Oracle在执行范例PL/SQL代码1、2、3时每次都是硬解析,但在执行范例PL/SQL代码4和5时会用软解析/软软解析,因为范例PL/SQL代码4和5可以重用之前执行的范例PL/SQL代码3中目标SQL(即INSERT INTO T_BG_20170610_LHR VALUES(:N,:V))的解析树和执行计划。在执行范例PL/SQL代码6时是硬解析,这意味着对于此目标SQL而言,其所在的Parent cursor下会有4个Child Cursor:

LHR@orclasm > col sql_text format a60

LHR@orclasm > SELECT SQL_TEXT,SQL_ID,VERSION_COUNT,EXECUTIONS FROM V$SQLAREA WHERE SQL_TEXT LIKE 'INSERT INTO T_BG_20170610_LHR VALUES%';

SQL_TEXT                                                     SQL_ID        VERSION_COUNT EXECUTIONS

------------------------------------------------------------ ------------- ------------- ----------

INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)                  01g03pruhphqc             4          6

LHR@orclasm > SELECT SQL_TEXT,SQL_ID,D.CHILD_NUMBER,D.CHILD_ADDRESS,EXECUTIONS FROM V$SQL D WHERE SQL_ID = '01g03pruhphqc';

SQL_TEXT                                                     SQL_ID        CHILD_NUMBER CHILD_ADDRESS    EXECUTIONS

------------------------------------------------------------ ------------- ------------ ---------------- ----------

INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)                  01g03pruhphqc            0 00000000AA902CE8          1    <<----对应PL/SQL代码1

INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)                  01g03pruhphqc            1 00000000AAA47348          1    <<----对应PL/SQL代码2

INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)                  01g03pruhphqc            2 00000000AAAF7A28          3    <<----对应PL/SQL代码3、4、5

INSERT INTO T_BG_20170610_LHR VALUES(:N,:V)                  01g03pruhphqc            3 0000000095DA4B00          1    <<----对应PL/SQL代码6

LHR@orclasm > SELECT d.SQL_ID,D.CHILD_NUMBER,D.BIND_LENGTH_UPGRADEABLE FROM V$SQL_SHARED_CURSOR D WHERE D.SQL_ID = '01g03pruhphqc';

SQL_ID        CHILD_NUMBER B

------------- ------------ -

01g03pruhphqc            0 N

01g03pruhphqc            1 Y

01g03pruhphqc            2 Y

01g03pruhphqc            3 Y

下面查询分配的内存空间大小:

LHR@orclasm > SELECT B.CHILD_NUMBER,B.CHILD_ADDRESS,D.BIND_NAME,D.POSITION,D.DATATYPE,D.MAX_LENGTH FROM v$sql_bind_metadata d,V$SQL b WHERE d.ADDRESS=b.CHILD_ADDRESS AND b.SQL_ID='01g03pruhphqc' ORDER BY B.CHILD_NUMBER,D.POSITION;

CHILD_NUMBER CHILD_ADDRESS    BIND_NAME                        POSITION   DATATYPE MAX_LENGTH

------------ ---------------- ------------------------------ ---------- ---------- ----------

0 00000000AA902CE8 N                                       1          2         22

0 00000000AA902CE8 V                                       2          1         32

1 00000000AAA47348 N                                       1          2         22

1 00000000AAA47348 V                                       2          1        128

2 00000000AAAF7A28 N                                       1          2         22

2 00000000AAAF7A28 V                                       2          1       2000

3 0000000095DA4B00 N                                       1          2         22

3 0000000095DA4B00 V                                       2          1       4000

从上述查询结果可以看到,Child Cursor 0中文本型绑定变量V确实被分配了32字节的内存空间,Child Cursor 1中文本型绑定变量V确实被分配了128字节的内存空间,Child Cursor 2中文本型绑定变量V被分配了2000字节的内存空间,Child Cursor 3中文本型绑定变量V被分配了4000字节的内存空间,同时这三个Child Cursor中的数值型绑定变量N统一被分配了22字节的内存空间。

通过上述示例可以看出:为了避免不必要的硬解析,在PL/SQL代码中处理带文本型绑定变量的目标SQL时,应该将这些文本型绑定变量的定义长度保持在同一个等级,当然,这里最好是定义成一个统一的长度,比如VARCHAR2(4000)。



>

>

>

>

>
>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

><

>

>

>

>>>>

>

>
>

>

>



Oracle绑定变量分级(Bind Graduation)相关推荐

  1. Oracle 绑定变量 详解 .

    之前整理过一篇有关绑定变量的文章,不太详细,重新补充一下. Oracle 绑定变量 http://blog.csdn.net/tianlesoftware/archive/2009/10/17/467 ...

  2. java绑定变量怎么加_在JAVA 源程序中编写SQL语句时使用ORACLE 绑定变量

    在JAVA中的SQL 语句的编写方面,没有使用ORACLE 绑定变量,很大程度上降低了数据库的性能,表现在两个方面: 1.SQL语句硬分析(Hard Parse)太多,严重消耗CPU资源,延长了SQL ...

  3. oracle绑定变量写法,关于Oracle绑定变量的个人理解及使用场景

    关于Oracle绑定变量 摘自--Oracle 11g concept 中英文对照版 使用了绑定变量能提高性能主要是因为这样做可以尽量避免不必要的硬解析而节约了时间,同时节约了大量的CPU资源. 绑定 ...

  4. oracle绑定变量赋值,Oracle教程之绑定变量

    绑定变量是指在sql语句的条件中使用变量而不是常量.比如shared pool里有两条sql语句, select * from tab1 where col1=1; select * from tab ...

  5. 绑定变量和BIND PEEKING

    http://www.oraclefans.cn/forum/showtopic.jsp?rootid=5467&CPages=1 http://blog.csdn.net/tianlesof ...

  6. 解决oracle绑定变量重复,基于ORACLE SQL优化之绑定变量(4)

    绑定变量的使用过程当中,oracle建议绑定变量的个数不宜太多.目标SQL的SQL文本中的绑定变量个数不宜太多,否则可能会导致目标SQL总的执行时间大幅度的增长.增长的时间主要消耗在执行目标SQL时对 ...

  7. oracle变量绑定代码,Oracle 绑定变量

    oracle 中,对于一个提交的sql语句,存在两种可选的解析过程,一种叫做硬解析,一种叫做软解析.https://www.cndba.cn/Dave/article/1275 一个硬解析需要经解析, ...

  8. ORACLE 绑定变量用法总结

    http://blog.csdn.net/wh62592855/article/details/4778343 之前对ORACLE中的变量一直没个太清楚的认识,比如说使用:.&.&&a ...

  9. oracle绑定变量过多,oracle - 在SQL Plus中使用绑定变量并返回多行? - 堆栈内存溢出...

    这是一个愚蠢的问题,但我似乎无法解决. 我有一个查询在OCI程序中引起麻烦,因此我想在SQL * Plus中手动运行它以检查是否有任何区别. 这是查询: select e.label as doc_n ...

最新文章

  1. k8s,nginx备份日志脚本
  2. 动态创建asp.net控件之我见
  3. 再观手游市场新风口-二次元游戏
  4. 通过QUIC 0-RTT建立更快的连接
  5. c语言五子棋代码_基于控制台的C语言贪吃蛇
  6. python中的排序方法都有哪些_Python中的排序方法sort(),sorted(),argsort()等
  7. 车羊问题c语言编程,C语言-人狼羊菜问题-最容易看懂的解决方法及代码
  8. electron 打包把node代理服务打包进去_专题:让C++给node做技术加持(三)编译electron本地模块踩坑记
  9. ubuntu和linux服务器,Linux服务器系统CentOS和Ubuntu Server如何选择? | 偶乃秋辰
  10. 第二章--电商设计表
  11. feign整合sential_Sentinel 和 Feign 集成时,方法名称写错
  12. 大数据分析,利用向外扩展技术深入挖掘商业价值
  13. 微软sccm服务器,微软SCCM是什么?
  14. 基于机器学习的笑脸检测
  15. 记录一次 CPU sy 过高的排查经历
  16. python后端工程师学什么_成为后端工程师需要学习什么
  17. 林下仿野生天麻的种植技术方法
  18. Docker 下载安装 Docker 配置镜像加速器
  19. 小心肝队-冲刺日志(第八天)
  20. 华安基金高管事发 基金业突遇“公信力寒流”(ZT)

热门文章

  1. python 遍历内嵌tuple_python内置数据结构list、set、dict、tuple(一)
  2. 21天jmeter打卡day2-环境搭建
  3. java学习_Java学习路线图
  4. linux镜像文件太大不好下载_Linux系统挂接命令的使用方法
  5. MATLAB 撰写word
  6. maven打包忽略注解_Maven打包时遇到的一些坑和解决方案
  7. python http服务器_Python简单http服务实现
  8. java基本变量的堆栈_JAVA经验谈:尽可能使用堆栈变量
  9. java作用域对象笔记_Java学习笔记(七)——对象
  10. php月末,php获取月头月末