v$sql v$sqlarea和父游标 子游标记载01

这个双休去了常州,blog好久没更新了,又偷懒了。今早群里在聊绑定变量,其实对于绑定变量自己也是糊里糊涂的,对于实质的还远远理解不够,pub的老谢给了我们一篇帖子,细细读下去还是受益匪浅啊。

http://www.itpub.net/thread-965919-1-1.html

oltp事务处理系统中,绑定变量和索引可以说是这个系统中比较重要的两部分,对于索引自己慢慢也有了一定的理解,在索引那些事中自己还是整理了一些心得的。从老谢的帖子中让自己以前的有些错误理解纠正了,记得看杨老大的blog中关于分页查询的分析也让自己恍然大悟,(看过老杨大的物化视图,大师如此认真,后辈们真是太不勤奋了。)对于oracle的学习需要的更多是认真吧!

这里摘要一下老谢的帖子一些信息:

SQL> select * from tt where id=1;

ID NAME
---------- ----------------------------------------
1 test

SQL> select * from tt where id=2;

ID NAME
---------- ----------------------------------------
2 test

SQL> variable i number;
SQL> exec :i :=1;

PL/SQL
过程已成功完成。

SQL> select *from tt where id=:i;

ID NAME
---------- ----------------------------------------
1 test

SQL> exec :i :=2;

PL/SQL
过程已成功完成。

SQL> select *from tt where id=:i;

ID NAME
---------- ----------------------------------------
2 test

SQL> print i;

I
----------
2

SQL> select sql_text,parse_calls from v$sql where sql_text like 'select * from t
t where id=%';

SQL_TEXT PARSE_CALLS
------------------------------------------------------------ -----------
select * from tt where id=2 1
select * from tt where id=1 1
select * from tt where id=:i 2
SQL>
从上面试验发现绑定变量i的使用使查询id=1id=2sqlselect *from tt where id=:i得以重复使用,从而避免了hard parse,这里的PARSE_CALLS2包括了一次soft parse.

从上面可以推翻自己以前记载的静态sql都会使用绑定变量的错误理解。绑定变量的使用跟静态和动态sql没有绝对关系!

这里顺便提一下关于v$sql视图的一些column的含义:

Hash_value: sql语句的hash值,这个hash值用来判断sql语句是否可以共享使用。

Address:sql语句在sga的地址。

Executions 执行次数

Optimizer_modesql执行的优化器模式

Buffer_gets:子指针的buffer gets数量

Disk_reads:子指针disk read的次数

Optimizer_costsql执行的cost成本

Hash_value:library cache父指针的hash value

End_of_fetch_count:完整执行sql的次数

Loads:对象被装载或重载的次数

Row_processes:sql语句返回的行数

Cpu_time:分析 执行和提取所消耗的时间(微秒)

Elapsed_time:客观上分析 执行 提取所消耗的时间

Sharable_memory:cursor使用的共享内存总数

Persistent_memory:cursor使用的常驻内存总数

Runtime_memorycursor使用的内存总数

V$sqlarea视图:

V$sqlarea视图和v$sql视图大致结构相同,其中的v$sqlarea有列VERSION_COUNT字段,其中代表的就是对于此父游标的子游标的数量,也就是在v$sql里面的子游标的sql记录的数量。在v$sql中有一列CHILD_NUMBER字段,表示该字游标的编号. v$sqlarea列出了共享SQL区(Shared SQL Area)中的SQL统计信息,这些SQL按照SQL文本的不同,每条会记录一行统计数据

父游标和子游标有点糊涂了,自己也不能说到很好的表达来描述,还是直接看例子吧!

SQL> alter system flush shared_pool;

System altered

SQL> conn ashuang/ashuang;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as ashuang

SQL> select count(1) from test01;

COUNT(1)

----------

23

SQL> conn test01/test01;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as test

SQL> select count(1) from test01;

COUNT(1)

----------

23

SQL> col sql_text for a40;

SQL> select sql_text,executions,loads,version_count from v$sqlarea where sql_text like '%select count(1) from test01%';

SQL_TEXT EXECUTIONS LOADS VERSION_COUNT

---------------------------------------- ---------- ---------- -------------

select count(1) from test01 1 1 2

select sql_text,executions,loads,versio 1 1 1

n_count from v$sqlarea where sql_text li

ke '%select count(1) from test01%'

SQL> select sql_text,executions,loads,child_number,parsing_schema_name from v$sql where sql_text like '%select count(1) from test01%';

SQL_TEXT EXECUTIONS LOADS CHILD_NUMBER PARSING_SCHEMA_NAME

---------------------------------------- ---------- ---------- ------------ ------------------------------

select count(1) from test01 1 1 0 ASHUANG

select sql_text,executions,loads,versio 1 1 0 TEST

n_count from v$sqlarea where sql_text li

ke '%select count(1) from test01%'

select sql_text,executions,loads,child_ 1 1 0 TEST

number,parsing_schema_name from v$sql wh

ere sql_text like '%select count(1) from

test01%'

在查询过程中虽然sql语句的文本相同,但是实际我们查询的表却是不同的用户,sql的执行计划等都不相同,实际就产生了两个子游标存储相应的sql的执行计划和解析树等。

当一条sql语句出现时,oracle会在库缓存中分配内存,将父游标保存进去,同时v$sqlarea中会记在父游标一条记录,然后如果同一条sql语句出现时,此时如果用户不同或者optimizer_mode不同 绑定量表分级的情况可能导致执行计划不同,从而生成多个子游标。

上面的实验中是用多个用户的来验证子游标的存在,其实在不同的optimizer_mode下同一个用户的同一个sql也会产生多个子游标。

这里就不贴出繁琐的代码了,说下测试的思路:

Select count(1) from test01;

Alter session set optimizer_mode=fistr_rows

然后再次查询Select count(1) from test01;可以明显的看出会生产两个子游标。

那么父游标与子游标的最终意义了,由于一个sql语句中需要创建游标,然后分析语句运行查询,需要一个游标来指定sql的相关内存地址从而来判断是否能共享sql语句,也就是减小不必要的硬解析啊!

哎准备整理绑定变量的,不知不觉中说到了v$sqlv$sqlarea视图和父子游标去了,后续继续更新!

[@more@]

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

转载于:http://blog.itpub.net/25362835/viewspace-1056487/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值