v$sql v$sqlarea v$sql_shared_cursor及游标

1.v$sql和v$sqlarea的区别
v$sql和v$sqlarea从某种意义上具有父子关系。即v$sqlarea保存的是父游标的sql信息,而v$sql保存的是子游标的sql的信息。在v$sqlarea里面有一列VERSION_COUNT字段,其中代表的就是对于此父游标的子游标的数量,也就是在v$sql里面的子游标的sql记录的数量。在v$sql中有一列CHILD_NUMBER字段,表示该字游标的编号。可以说v$sqlarea和v$sql是一对多的父子关系。

2.父游标和子游标
每种类型的dml语句都需要如下阶段:
Create a Cursor         创建游标
Parse the Statement     分析语句
Bind Any Variables      绑定变量
Run the Statement       运行语句
Close the Cursor        关闭游标
当数据库第一次对一条SQL语句进行硬解析的时候,会在库缓存中分配一些内存,并将新产生的父游标保存进去。与父游标有关的关键信息室这个SQL语句的文本,这个时候,会在v$sqlarea里面插入一条记录。那么,在什么情况下会产生子游标呢,当数据库又碰到一条完全相同SQL语句,但是语句的执行计划和执行环境发生了变化,比如由于绑定变量窥测而产生的不一致的执行计划,由于SQL的初始化参数optimizer_mode的不同以及绑定变量分级的情况都会产生子游标,当产生子游标的时候,会在v$sql里面插入一条记录。并且v$sqlarea里的VERSION_COUNT字段的值会加1。
eg:
--多个SQL语句只有在它们的文本完全一致的情况下才能共享一个父游标,这是最基本的要求。
--窗口1执行
sys/SYS>select * from t;

no rows selected

sys/SYS>select * from t;

no rows selected

sys/SYS>SELECT * from t;

no rows selected
--窗口2执行
sys/SYS>select hash_value,sql_text,executions from v$sqlarea where sql_text like '%from t';

HASH_VALUE SQL_TEXT                                 EXECUTIONS
---------- ---------------------------------------- ----------
3542409071 SELECT * from t                                   1
 520543201 select * from t                                   2
可以看到由于SQL文本不同产生了两个父游标。
sys/SYS>select HASH_VALUE,child_number,sql_text from v$sql where sql_text like '%from t';

HASH_VALUE CHILD_NUMBER SQL_TEXT
---------- ------------ ----------------------------------------
 520543201            0 select * from t
3542409071            0 SELECT * from t
在v$sql里面也插入了两条子游标的记录,但是CHILD_NUMBER都是0,其实对应的就是父游标。
现在再来看下由于optimizer_mode的不同而产生子游标的情况。
--窗口1执行
sys/SYS>alter session set optimizer_mode=all_rows;

Session altered.

sys/SYS>select * from tt;

no rows selected

sys/SYS>alter session set optimizer_mode=first_rows_10;

Session altered.

sys/SYS>select * from tt;

no rows selected

--窗口2执行

sys/SYS>select hash_value,sql_text,executions,VERSION_COUNT from v$sqlarea where sql_text like '%from tt';

HASH_VALUE SQL_TEXT                                 EXECUTIONS VERSION_COUNT
---------- ---------------------------------------- ---------- -------------
3762890390 select * from tt                                  2             2

sys/SYS>select HASH_VALUE,child_number,sql_text from v$sql where sql_text like '%from tt';

HASH_VALUE CHILD_NUMBER SQL_TEXT
---------- ------------ ----------------------------------------
3762890390            0 select * from tt
3762890390            1 select * from tt
可以看到,SQL文本是完全相同的,所以两个子游标共享了一个父游标。但是由于optimizer_mode的不同,所以生成了2个子游标。
如果产生了子游标,那么说明肯定产生了某种mismatch,那么如何来查看是何种原因产生了mismatch呢?这就要通过v$sql_shared_cursor了。
sys/SYS>select kglhdpar, address,auth_check_mismatch, translation_mismatch,OPTIMIZER_MISMATCH
  2  from v$sql_shared_cursor
  3  where kglhdpar in
  4  ( select address
  5    from v$sql
  6    where sql_text like '%from tt');

KGLHDPAR ADDRESS  A T O
-------- -------- - - -
89BB8948 89BB83CC N N N
89BB8948 89BB5E78 N N Y
可以看到OPTIMIZER_MISMATCH列第二行的值为Y,这说明了正是由于optimizer_mode的不同而产生了子游标。
最后,父游标和子游标的意义何在?其实一切都是为了共享。以减少再次解析的资源浪费。

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

转载于:http://blog.itpub.net/21805468/viewspace-620710/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值