作者:小佛瞌睡蓝 | 来源:互联网 | 2014-07-13 17:52
解析操作的结果是将一个父游标和子游标保存到librarycache中,将它们保存到sga,是为了重用它们,从而避免硬解析。在什么情况下可以重用父游标和子游标呢?父游标的关键信息是sql文本;子游标的关键信息是执行...SyntaxHighlighter.all();
解析操作的结果是将一个父游标和子游标保存到library cache中,将它们保存到sga,是为了重用它们,从而避免硬解析。
在什么情况下可以重用父游标和子游标呢?
父游标的关键信息是sql文本;子游标的关键信息是执行计划和执行环境。
通过v$sqlarea查询父游标的信息;v$sql查询子游标的信息。
通 过address、hash_value、child_number来确定一个游标。父游标由address和hash_value唯一确定,10g更加 常用sql_id来替代address和hash_value;子游标由address、hash_value、child_number唯一确定。
1、父游标无法被共享的情形
父游标的关键信息是sql文本,因此多个sql只有在它们的文本完全一致的情况下才可以共享同一个父游标,这是最基本的要求。 www.2cto.com
SQL> select * from zhhtest where id=1;
SQL> SELECT * FROM ZHHTEST where id=1;
SQL> select * from zhhtest where id=1 ;
SQL> select * from zhhtest where id=1;
上面四条sql:第一条和第四条完全一致;第二条和第三条sql在大小写和空格上不同。
通过查询v$sqlarea,我们可以确认
系统创建了3个父游标,请注意执行次数。
SQL> select sql_id,sql_text,executions from v$sqlarea where sql_text like '%id=1%';
SQL_ID SQL_TEXT EXECUTIONS
------------- -------------------------------------------------- ----------
2z33s0z9wp798 select sql_id,sql_text,executions from v$sqlarea w 1
here sql_text like '%id=1%'
b5v00mn1t6x0v SELECT * FROM ZHHTEST where id=1 1
gtyypghg9qy40 select * from zhhtest where id=1 1
ckpuxaxjrm1qq select * from zhhtest where id=1 2
2、可以共享父游标而无法共享子游标的情形
子游标的关键信息是执行计划和执行环境,如果执行环境发生了变化,执行计划也有可能发生变化。
只有在拥有共同父游标并且执行环境也兼容的情况下,多个sql才能共享同一个子游标。
SQL> alter session set optimizer_mode=all_rows;
Session altered. www.2cto.com
SQL> select count(1) from zhhtest;
COUNT(1)
----------
300
SQL> alter session set optimizer_mode=first_rows;
Session altered.
SQL> select count(1) from zhhtest;
COUNT(1)
----------
300
从v$sql查询,创建了一个父游标(b2kjsg0h8rt08)和两个子游标(0/1),请注意这两个子游标使用了同一个执行计划(PLAN_HASH_VALUE)。
SQL> select prev_sql_id from v$session where sid=(select sid from v$mystat where rownum=1);
PREV_SQL_ID
-------------
b2kjsg0h8rt08
SQL> select sql_id,child_number,sql_text,optimizer_mode,plan_hash_value from v$sql where sql_id='b2kjsg0h8rt08';
SQL_ID CHILD_NUMBER SQL_TEXT OPTIMIZER_ PLAN_HASH_VALUE
------------- ------------ -------------------------------------------------- ---------- ---------------
b2kjsg0h8rt08 0 select count(1) from zhhtest ALL_ROWS 2173948436
b2kjsg0h8rt08 1 select count(1) from zhhtest FIRST_ROWS 2173948436 www.2cto.com
3、v$sql_shared_cursor
通过查询该视图,可以了解到是因为哪种不匹配导致多个子游标的产生,可以发现没一个子游标(不包含第一个子游标0),为什么不能共享已经创建好的子游标。对于每种不兼容的类型,值有N(不是该类型导致)/Y(是该类型不匹配导致)
对于上面的例子,是因为优化器模式不同而生成新的子游标:
SQL> select child_number,optimizer_mode_mismatch from v$sql_shared_cursor where sql_id='b2kjsg0h8rt08';
CHILD_NUMBER OPTIMIZER_MODE_MISMATCH
------------ ------------------------------
0 N
1 Y
在 awr的SQL Statistics有一项是SQL ordered by Version Count,就是同一个父游标的子游标的数量。对于使用绑定变量程序,通过查询v$sql_shared_cursor可以发现都是因为 bind_mismatch导致生成多个子游标,这和绑定变量分级有关。
本文来自于无忧网客联盟