四 演示一个父游标产生3个子游标的示例,并分别说明每个子游标产生的原因
父游标:说白了就是SQL语句字符的哈希值,SQL文本一样它生成的哈希值就一样
子游标:区别相同SQL语句的一些其他不同
例如 1.不同用户下的相同SQL语句 2.不同权限下的相同SQL语句
父子游标:oracle要知道它们是同一个语句可共享相同的信息,还是不是同一个语句要区别对待
实验
LEO1@LEO1> conn leo1/leo1 切换到leo1用户
Connected.
LEO1@LEO1> create table t1 as select * from dba_objects; 创建t1表
Table created.
LEO1@LEO1> select count(*) from t1; 这是leo1用户下的t1表
COUNT(*)
----------
71973
LEO1@LEO1> conn leo2/leo2 切换到leo2用户
Connected.
LEO2@LEO1> create table t1 as select * from dba_objects; 也可以创建t1表
Table created.
LEO2@LEO1> select count(*) from t1; 这是leo2用户下的t1表
COUNT(*)
----------
71974
LEO2@LEO1> conn scott/tiger 切换到scott用户
Connected.
SCOTT@LEO1> create table t1 as select * from dba_objects; 又建立了一张t1表
Table created.
SCOTT@LEO1> select count(*) from t1; 这是scott用户下的t1表
COUNT(*)
----------
71975
LEO2@LEO1> select table_name,owner from dba_tables where table_name ='T1';
TABLE_NAME OWNER
---------- ------------------------------
T1 LEO2
T1 LEO1
T1 SCOTT
对象名相同,但是所属不同的用户,只要SQL语句一样,它的SQL_ID就一样,这时子游标就派上用场了,它可以区分不同属性的相同SQL。
SCOTT@LEO1> select sql_id,child_number,sql_text,parse_calls,plan_hash_value,loads from v$sql where sql_text='select count(*) from t1';
SQL_ID CHILD_NUMBER SQL_TEXT PARSE_CALLS PLAN_HASH_VALUE LOADS
------------- ------------ -------------------------------------------------- ----------- --------------- ------------------------- ----------
5bc0v4my7dvr5 0 select count(*) from t1 1 3724264953 1
5bc0v4my7dvr5 1 select count(*) from t1 1 3724264953 1
5bc0v4my7dvr5 2 select count(*) from t1 1 3724264953 1
SQL_ID:哈希值相同就认为是同一个父游标,用子游标来区分不同属性的相同SQL
CHILD_NUMBER:这个字段不同,说明oracle知道这是3个用户下的相同SQL语句
LOADS:都做了1次硬解析,说明oracle知道这是3个不完全相同的SQL语句
SCOTT@LEO1> select sql_id,child_number,child_address,sql_text from v$sql where sql_text='select count(*) from t1';
SQL_ID CHILD_NUMBER CHILD_ADDRESS SQL_TEXT
------------- ------------ ---------------- --------------------------------------------------
5bc0v4my7dvr5 0 000000007AEEDC28 select count(*) from t1
5bc0v4my7dvr5 1 000000007DB27088 select count(*) from t1
5bc0v4my7dvr5 2 000000007AEDCB88 select count(*) from t1
CHILD_ADDRESS:这列有3个值,说明oracle认为一个父游标5bc0v4my7dvr5对000000007AEEDC28
000000007DB27088 000000007AEDCB88 三个子游标,可知这3条看似相同的SQL在某些方面存在差异。如果在日常检查中发现有多个版本,要了解一下是什么原因导致出现这么多版本的!
PLAN_HASH_VALUE:这个列显示,这3条SQL语句都使用的是相同的执行计划,因为它们的执行计划哈希值都相同,我们输出执行计划来比较一下就明了了。
SCOTT@LEO1> select count(*) from t1;
Execution Plan
----------------------------------------------------------
Plan hash value: 3724264953 这是scott用户的哈希值
SCOTT@LEO1> conn leo1/leo1
Connected.
LEO1@LEO1> set autotrace trace explain
LEO1@LEO1> select count(*) from t1;
Execution Plan
----------------------------------------------------------
Plan hash value: 3724264953 这是leo1用户的哈希值
LEO1@LEO1> conn leo2/leo2
Connected.
LEO2@LEO1> set autotrace trace explain
LEO2@LEO1> select count(*) from t1;
Execution Plan
----------------------------------------------------------
Plan hash value: 3724264953 这是leo2用户的哈希值
执行计划中的哈希值和动态性能视图中的值一样,虽说不是完全一样的SQL,但走的执行计划全相同
LEO2@LEO1> select sql_id,auth_check_mismatch from v$sql_shared_cursor where sql_id='5bc0v4my7dvr5';
SQL_ID A
------------------------
5bc0v4my7dvr5 N
5bc0v4my7dvr5 Y
5bc0v4my7dvr5 Y
小结:对上述三条SQL_ID,进行不匹配检查,也显示不可共享游标信息。
本文转自 leonarding151CTO博客,原文链接:http://blog.51cto.com/leonarding/1131511,如需转载请自行联系原作者