WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: Oracle
2013-04-01 17:09:54
并不是用了绑定变量就一定都会游标共享,下面我们介绍的就是一种例子。
BIND_MISMATCH导致VERSION COUNT过多的原因解释:
This is due to the bind buffer mismatch of the current child cursor.
If oracle is unable to bind the current value to the existing child cursors bind buffer,
oracle upgrades the existing child cursor with a high bind buffer. This will force the query to
do a hard parse and a new child cursor will be created.
对于绑定变量,ORACLE根据变量长度进行了分级,对于VARCHAR2类型共有如下4级:
第一级:1-32
第二级:33-128
第三级:129-2000
第四级:2000+
对于定义的变量在同一级可以共享游标,否则会生成子游标,如下:
SQL> desc t
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
X VARCHAR2(30)
SQL> variable v_x varchar2(32)
SQL> exec :v_x:='a';
PL/SQL 过程已成功完成。
SQL> select * from t where x=:v_x;
未选定行
SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';
SQL_ID CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 1 1
SQL> variable v_x varchar2(33)
SQL> exec :v_x:='a';
PL/SQL 过程已成功完成。
SQL> select * from t where x=:v_x;
未选定行
SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';
SQL_ID CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 1 1
1pqg8dpwthcp3 2 1
SQL> select child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';
CHILD_NUMBER B
------------ -
1 N
2 Y
SQL> variable v_x varchar2(129)
SQL> exec :v_x:='a';
PL/SQL 过程已成功完成。
SQL> select * from t where x=:v_x;
未选定行
SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';
SQL_ID CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 1 1
1pqg8dpwthcp3 2 1
1pqg8dpwthcp3 3 1
SQL> select child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';
CHILD_NUMBER B
------------ -
1 N
2 Y
3 Y
SQL> variable v_x varchar2(2001)
SQL> exec :v_x:='a';
PL/SQL 过程已成功完成。
SQL> select * from t where x=:v_x;
未选定行
SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';
SQL_ID CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 1 1
1pqg8dpwthcp3 2 1
1pqg8dpwthcp3 3 1
1pqg8dpwthcp3 4 1
SQL> select child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';
CHILD_NUMBER B
------------ -
1 N
2 Y
3 Y
4 Y
具体可以参考:High Version Count Due To BIND_MISMATCH [ID 336268.1]
ORACLE文档说可以通过设置10503事件来搞定这个问题,在我的测试环境却不行。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> alter system flush shared_pool;
系统已更改。
/home/cpicsrv/yansp > oerr ora 10503
10503, 00000, "enable user-specified graduated bind lengths"
// *Cause:
// *Action:
SQL> alter session set events '10503 trace name context forever ,level 4096';
会话已更改。
SQL> variable v_x varchar2(32)
SQL> exec :v_x:='a';
PL/SQL 过程已成功完成。
SQL> select * from t where x=:v_x;
未选定行
SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';
SQL_ID CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 0 1
SQL> variable v_x varchar2(33)
SQL> exec :v_x:='a';
PL/SQL 过程已成功完成。
SQL> select * from t where x=:v_x;
未选定行
SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';
SQL_ID CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 0 1
1pqg8dpwthcp3 1 1
SQL> select child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';
CHILD_NUMBER B
------------ -
0 N
1 Y
SQL>