提到软解析(soft prase)和硬解析(hard prase),就不能不说一下Oracle对sql的处理过程。当你发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行几个步骤的处理过程:
1、语法检查(syntax check)
检查此sql的拼写是否语法。
2、语义检查(semantic check)
诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3、对sql语句进行解析(prase)
利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。
4、执行sql,返回结果(execute and return)
Sql 执行的流程分成3部分:
解析部分(Parse): Server process将sql语句在Shared pool(共享池)里解析为执行计划
执行部分(Execute): Server process根据执行计划在DB buffer cache和数据文件里提取数据.
获取数据部分(Fetch): 获得数据并返回给用户.
所以可以看出解析部分是在SGA里面 Share pool里完成的.
可以从V$sgainfo 视图查看shared pool 的当前大小信息
Share pool里面分成许多个部分, 我们可以大概看成3个主要部分:(实际上还有Result cache等部分)
分别是Free 空间, Library Cache(库缓存) 和 RowCache(字典缓存)
如图:
Shared pool
而整个Shared pool的作用是用来缓存用户的sql 语句和 和对应执行计划的.
当一条sql语句, 从user client传到Server Process(PGA)里时, Server Process会拿着sql去Share pool里面.
Server process首先会判断sql语句的语法是否正确, sql语句涉及的对象是否有权限.
如果上面两步没问题了,那么会到Share pool 里的 Library Cache寻找有无相同的sql语句和对应的缓存计划.
所以Server Process在share pool里头3个动作是:
1. 判断语法合法性
2. 判断涉及对象权限
3. 到Library Cache里寻找缓存的sql和对应执行计划.
好了由第3步得知Share pool缓存的sql语句和执行计划实在是缓存在share pool里的Libaray Cache里面的.
下面简单介绍下Library cache和 Rowcache
Library cache : 在share pool里用来缓存用户执行过的sql语句和对应执行计划.
在Oracle 10g 里可以用select * from v$sgastat where pool = ‘shared pool’ and name ='library cache’来查看当前library cache的大小:
(11g不适用…)
注意: 数据库负载越重free memory越小.
Rowcache : 数据字典缓存, 作用就是存放数据字典的数据啦.
为什么要存放数据字典呢, 因为上面的第2步:判断涉及对象权限 和 硬解析中要访问大量的表/索引…对象,而这些信息都是存放在数据字典中的.
好了现在说明下什么是软解析:
当Server process在Library cache里找到现成的执行计划时,就直接可以利用这个执行计划去执行sql语句了. 我们就叫个得到执行计划的过程叫软解析所以软解析只包含上述3步动作.
硬解析:
当sql语句是第一次运行或者其他原因, Library cache里面没有对应的执行计划,只能由Server process自己去解析成执行计划, 就是硬解析了.
硬解析也是在library cache里完成的.
因为1个sql语句有多种执行方案. 解析过程中必须访问大量的数据库对象信息才能得到1个最佳的执行方案成为执行计划,所以Oracle才会吧数据字典缓存Rowcache 放到shared pool 与librarycache配合.
所以硬解析包含4步: 上述3步再加上解析成执行计划的这一步, 而第4步是相当耗费资源的, 所以通常我们会遇到第一次执行查询数据很慢, 然后第2 第3次就很快了, 这里就有软解析的功劳(当然也有 DB buffer cache的作用).
所以我们希望shared pool 里的软解析越多越好.
可以查看v$sgastat查看硬解析和软解析次数
如上图
Parse time cpu: 数据库启动以来解析花费的cpu时间
parse time elapsed: 解析总时间
parse count(total) : 解析总次数
parse count(hard): 硬解析次数
parse count(failures) : 解析失败的次数
parse count(describe) : Total number of parse calls on a describe cursor, 这种解析耗费资源介于硬解析与软解析之间 11g独有
用total次数减去上面3中解析的次数就是软解析次数了.