ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SQL共享:父游标和子游标的问题

SQL共享:父游标和子游标的问题

原创 Linux操作系统 作者:DataKW 时间:2013-06-24 18:30:51 0 删除 编辑
SQL共享:父游标和子游标的问题
http://www.2cto.com/database/201204/126502.html
 解析操作的结果是将一个父游标和子游标保存到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导致生成多个子游标,这和绑定变量分级有关。
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/27573546/viewspace-764726/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-08-12

  • 博文量
    132
  • 访问量
    298334