详解ORACLE数据库硬解析、软解析、软软解析
概述
TOM⼤叔的调优书中说过⼀句话,⼤概意思就是:如果有⼈让我写本怎样让ORACLE性能最慢的书的话我会将取消绑定变量(bind variable)做为书的第⼀章和最后⼀章,可见绑定变量的重要性。⽽绑定变量影响的实际上就是Oracle数据库的硬解析和软解析了。
Oracle数据库硬解析和软解析有相同的⼀步,⽽软软解析与硬解析、软解析完全不⼀样。
⼀、sql解析
众所周知,sql语句执⾏步骤⼤致如下:
1)语法检查(syntax check)
2)语义检查(symantic check): 对象是否存在,是否有权限。
3)sql解析(parse): 利⽤内部算法对sql进⾏解析,⽣成解析树及执⾏计划。
4)执⾏sql,返回结果(execute and return)
⼀个sql 语句,进⼊到数据库后,server process 会拿着sql语句到shared pool中的library cache ⾥边去,看sql语句以前是否有执⾏过。也就是在library cache ⾥⾯看有没有这条sql语句以及sql语句所对应的执⾏计划。(此过程是通过对传递进来的SQL语句使⽤HASH函数运算得出HASH值,与共享池中现有语句的HASH值进⾏⽐较看是否⼀⼀对应。现有数据库中SQL语句的HASH值我们可以通过访问vsql、vsql、vsqlarea、v$sqltext等数据字典中的HASH_VALUE列查询得出。)
⼆、涉及解析的概念
1、硬解析
硬解析(Hard Parse)是指Oracle在执⾏⽬标SQL时,在库缓存(Library Cache)中不到可以重⽤的解析树和执⾏计划,⽽不得不从头开始解析⽬标SQL并⽣成相应的⽗游标(Parent Cursor)和⼦游标(Child Cursor)的过程。
硬解析实际上有两种类型:⼀种是在库缓存中不到匹配的⽗游标(Parent Cursor),此时Oracle会从头开始解析⽬标SQL,新⽣成⼀个⽗游标和⼀个⼦游标,并把它们挂在对应的HashBucket中;另外⼀种是到了匹配的⽗游标但未到匹配的⼦游标,此时Oracle也会从头开始解析该⽬标SQL,新⽣成⼀个⼦游标,并把这个⼦游标挂在对应的⽗游标下。
硬解析过程:
1.语法、语义及权限检查;
2.查询转换(通过应⽤各种不同的转换技巧,会⽣成语义上等同的新的SQL语句,如count(1)会转为count(*));
3.根据统计信息⽣成执⾏计划(出成本最低的路径,这⼀步⽐较耗时);
4.将游标信息(执⾏计划)保存到库缓存。
2、软解析
软解析(Soft Parse)是指Oracle在执⾏⽬标SQL时,在Library Cache中到了匹配的⽗游标(Parent Cursor)和⼦游标(Child Cursor),并将存储在⼦游标中的解析树和执⾏计划直接拿过来重⽤⽽⽆须从头开始解析的过程。
软解析过程:
1.语法、语义及权限检查;
2.将整条SQL hash后从库缓存中执⾏计划。
可以看出软解析对⽐硬解析省了三个步骤。
3、软软解析
软软解析(Soft Soft Parse)是指若参数SESSION_CACHED_CURSORS的值⼤于0,并且该会话游标所对应的⽬标SQL解析和执⾏的次数超过3次,则此时该会话游标会被直接缓存在当前会话的PGA中的。若该SQL再次执⾏的时候,则只需要对其进⾏语法分析、权限对象分析之后就可以直接从当前会话的PGA中将之前缓存的匹配会话游标直接拿过来⽤就可以了,这就是软软解析。
软软解析过程:
要完全理解软软解析先要理解游标的概念,当执⾏SQL时,⾸先要打开游标,执⾏完成后,要关闭游标,游标可以理解为SQL语句的⼀个句柄。
在执⾏软软解析之前,⾸先要进⾏软解析,MOS上说执⾏3次的SQL语句会把游标缓存到PGA,这个游标⼀直开着,当再有相同的SQL执⾏时,则跳过解析的所有过程直接去取执⾏计划。
三、实验论证
1、环境准备:
drop table test purge;
alter system flush shared_pool;
create table test as select * from dba_objects where 1<>1;
exec dbms_stats.gather_table_stats(ownname =>'sys',tabname =>'test');
2、硬解析
有兴趣的朋友看下执⾏计划就知道了。
select * from test where object_id=20; select * from test where object_id=30; select * from test where object_id=40; select * from test where object_id=50;
3、软解析
建议对⽐执⾏计划
var oid number;
exec :oid:=20;
select * from test where object_id=:oid; exec :oid:=30;oracle游标的使用
select * from test where object_id=:oid; exec :oid:=40;
select * from test where object_id=:oid; exec :oid:=50;
select * from test where object_id=:oid;
4、软软解析
begin
for i in 1..4
loop
execute immediate 'select * from test where object_id=:i' using i;
end loop;
end;
/
5、分析结果
可以看到软解析与软软解析相⽐,软软解析只是解析⼀次。
select sql_text,s.PARSE_CALLS,loads,executions from v$sql s where sql_text like 'select * from test where object_id%' order by 1,2,3,4;
字段解释:
PARSE_CALLS 解析的次数
LOADS 硬解析的次数
EXECUTIONS 执⾏的次数
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论