『ORACLE』父子游标(11g)--未完

来源:互联网 发布:软件销售代理协议 编辑:程序博客网 时间:2024/05/24 04:24
父游标是在进行硬解析时产生的,父游标里主要包含两种信息:SQL文本以及优化目标(optimizer goal),首次打开父游标被锁定,直到其他所有的session都关闭该游标后才被解锁。当父游标被锁定的时候是不能被LRU算法置换出library cache,只有在解锁以后才能置换出library cache,此时该父游标对应的所有子游标也同样被置换出library cache。v$sqlarea中的每一行代表了一个parent cursor,address表示其内存地址。


子游标在发生硬解析时,在产生父游标的同时,则跟随父游标会产生相应的子游标,此时V$SQL.CHILD_NUMBER的值为0。如果存在父游标,由于不同的运行环境,此时同样会产生新的子游标,新子游标的CHILD_NUMBER在已有子游标基础上以1为单位累计。子游标包括游标所有相关信息,如具体的执行计划、绑定变、OBJECT、权限、优化器设置等。子游标随时可以被LRU算法置换出library cache,当子游标被置换出library cache时,oracle可以利用父游标的信息重新构建出一个子游标来,这个过程叫reload。v$sql中的每一行表示了一个child cursor,根据hash value和address与parent cursor关联。child cursor有自己的address,即v$sql.child_address。


确定一个游标的三个主要字段:address、hash_value和child_number。sql_id可以唯一确定一个父游标,sql_id、child_number唯一确定一个子游标。




SYS@ENMO> ALTER SYSTEM FLUSH SHARED_POOL;


System altered.


SYS@ENMO> /


System altered.


SYS@ENMO> conn scott/tiger
Connected.
SCOTT@ENMO> select count(*) from emp;


  COUNT(*)
----------
        14


--记录了父游标
SYS@enmo1>select sql_id,sql_text from v$sqlarea where sql_text like 'select count(*) from scott.emp';


SQL_ID             SQL_TEXT
--------------------- ------------------
abj9tmfcs15bm  select count(*)from scott.emp


--记录了子游标
select sql_id,child_number,executions,loads from v$sql where sql_id='abj9tmfcs15bm';

SQL_ID                    CHILD_NUMBER   EXECUTIONS      LOADS
---------------------------- ----------------------- --------------------- --------------------

abj9tmfcs15bm            0                       1                        1


产生子游标的原因很多,
1:(SCHEMA)的改变,
2:比如优化器模式的改变:
3:绑定变量的窥视等,
如果你想确定是由那种原因造成的,需要查看v$sql_shared_cursor


对于刚才的例子,属于验证/事物检查不匹配
select sql_id,child_number,auth_check_mismatch from v$sql_shared_cursor where sql_id='abj9tmfcs15bm';


SQL_ID        CHILD_NUMBER A
------------- ----------------------- --
abj9tmfcs15bm            0 N



exec :v_eno:=7788
select ename,job,sal from emp where empno=:v_eno;                                                                    



select sql_id,sql_text,executions from v$sqlarea   -->首次查询后在v$sqlarea保存父游标且执行次数EXECUTIONS为1       
where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';          


select sql_id,hash_value,child_number,sql_text from v$sql -->查询视图v$sql查看该SQL对应的子游标,且CHILD_NUMBER为0 
where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';                  


exec :v_eno:=7369
select ename,job,sal from emp where empno=:v_eno;                                                                    


exec :v_eno:=7521
select ename,job,sal from emp where empno=:v_eno;                                                                    


select sql_id,sql_text,executions from v$sqlarea -->视图v$sqlarea中EXECUTIONS值为3,对应的SQL被执行了3次           
where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';  


视图v$sql中对应的子游标也实现了完全共享,保持CHILD_NUMBER为0                                                         
select sql_id,hash_value,child_number,sql_text from v$sql                                                          
where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';  
原创粉丝点击