这个双休去了常州,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=1和id=2的sqlselect *from tt where id=:i得以重复使用,从而避免了hard parse,这里的PARSE_CALLS=2包括了一次soft parse.
从上面可以推翻自己以前记载的静态sql都会使用绑定变量的错误理解。绑定变量的使用跟静态和动态sql没有绝对关系!
这里顺便提一下关于v$sql视图的一些column的含义:
Hash_value: sql语句的hash值,这个hash值用来判断sql语句是否可以共享使用。
Address:sql语句在sga的地址。
Executions: 执行次数
Optimizer_mode:sql执行的优化器模式
Buffer_gets:子指针的buffer gets数量
Disk_reads:子指针disk read的次数
Optimizer_cost:sql执行的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_memory:cursor使用的内存总数
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$sql和v$sqlarea视图和父子游标去了,后续继续更新!
[@more@]来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25362835/viewspace-1056487/ ,如需转载,请注明出处,否则将追究法律责任。