数据库

 首页 > 数据库 > Oracle > SQL共享:父游标和子游标的问题

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

分享到:
【字体:
导读:
         摘要:解析操作的结果是将一个父游标和子游标保存到librarycache中,将它们保存到sga,是为了重用它们,从而避免硬解析。在什么情况下可以重用父游标和子游标呢?父游标的关键信息是sql文本;子游标的关键信息是执行... SyntaxHighlighter.all(); ...

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

解析操作的结果是将一个父游标和子游标保存到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导致生成多个子游标,这和绑定变量分级有关。
 
 
 
本文来自于无忧网客联盟
SQL共享:父游标和子游标的问题
分享到:
oracle中的循环简析
oracle中的循环简析 一、LOOP 循环是最简单的循环,也是无限循环,只能用 EXIT 终止。   Sql代码   declare     starts number:=1;     counts number:=20;   begin     loop       dbms_output.put_line(starts);       starts:=starts+1;  www.2cto.com         exit when starts>=counts;     e...
oracle数据库语句级触发器和行级触发器的...
oracle数据库语句级触发器和行级触发器的使用 1.  行级触发器对DML语句影响的每个行执行一次。  语句级触发器对每个DML语句执行一次,如果在TABLE表中插入的数据为500行,那么这个表上的语句级触发器只执行一次,而行级的触发器就要执行500次了。  2.  语句级别触发器  是在表上或者某些情况下的视图上执行的特定语句...
  •         php迷,一个php技术的分享社区,专属您自己的技术摘抄本、收藏夹。
  • 在这里……