共计 2741 个字符,预计需要花费 7 分钟才能阅读完成。
如何进行 Oracle 数据库硬解析、软解析、软软解析联系与区别的分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
Oracle 数据库硬解析和软解析有相同的一步,而软软解析与硬解析、软解析完全不一样。
一、sql 解析
这里我们先简单 sql 语句执行步骤:
语法检查(syntax check)
语义检查(symantic check): 对象是否存在,是否有权限。
sql 解析(parse): 利用内部算法对 sql 进行解析,生成解析树及执行计划。
执行 sql,返回结果(execute and return)
首先了解一下 sql 解析时用到的内存结构 mdash; mdash;shared pool。
shared pool 是一块内存池,里边又被分成了很多小的区块,每个块有他们的作用:
free (空闲)
library cache (库缓存,缓存 sql 语句以及 sql 所对应的执行计划)
row cache (字典缓存 mdash; mdash; 库里有多少表,多少用户,多少个列,列的名字,列的数据类型,每个表多大等等都属于数据库自身信息。)
一个 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,新生成一个子游标,并把这个子游标挂在对应的父游标下。
硬解析过程:
语法、语义及权限检查;
查询转换 (通过应用各种不同的转换技巧,会生成语义上等同的新的 SQL 语句,如 count(1) 会转为 count(*));
根据统计信息生成执行计划(找出成本最低的路径,这一步比较耗时);
将游标信息 (执行计划) 保存到库缓存。
2. 软解析
软解析 (Soft Parse) 是指 Oracle 在执行目标 SQL 时,在 Library Cache 中找到了匹配的父游标 (Parent Cursor) 和子游标(Child Cursor),并将存储在子游标中的解析树和执行计划直接拿过来重用而无须从头开始解析的过程。
软解析过程:
语法、语义及权限检查;
将整条 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; 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 执行的次数
关于如何进行 Oracle 数据库硬解析、软解析、软软解析联系与区别的分析问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。