文档结构图:
举一个例子,什么是软解析
第一次执行:
要想初步了解什么是软解析与硬解析,首先要了解oracle在处理sql的一系列过程:
1、语法检查: 检查此sql的拼写是否语法。
2、语义检查: 诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3、对sql语句进行解析(prase): 利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。
4、执行sql,返回结果。
硬解析与软解析在oracle处理sql流程区别就在于:
既然软解析可以跳过对sql语句进行解析的过程,那么哪些sql种类可以进行软解析呢?
该部分的结论将在后面的实验中进行验证,但我们怎么判断是否执行了软解析,仅从sql的运行之间对比来判断吗?
实验的方法是执行类似的sql后,使用该sql查询parse count (hard)的值是否增加,如果前后两次的查询结果不增加,则上次执行的sql采用的是软解析。
实验一:DML语句与软解析测试sql 1:
测试sql 2:
测试方法:运行两次sql 1 ,在每次运行之后,运行sql 2
结果:
结论:DML语句支持软解析。
到此截止,能判断出DML 与 DQL 两种sql语句类型是支持软解析的,但并未判断出DDL是否支持软解析,该部分将会在“软解析的苛刻条件”中论证。
软解析与共享池
既然oracle在软解析的时候可以跳过“生成解析树、生成执行计划”的这个过程,那么肯定有“一片内存”可以保存这些生成的解析树和执行计划,这就是oracle共享池!
而oracle提供的动态视图v$sgastat可以展示系统分配的共享的内存结构:
1、 sharedpool(共享池):共享池主要由库缓冲区(共享SQL区和PL/SQL区)和数据字典缓冲区组成,它的作用是存放频繁使用的sql,在有限的容量下,数据库系统根据一定的算法决定何时释放共享池中的sql;如果容量不足时,释放不及时,会将命中率不频繁的,长时间不使用的sql放到磁盘缓冲区中,保证共享池中的容量不被使用耗尽;可以使用SELECT SQL_TEXT, SHARABLE_MEM FROM V$SQL WHERE SHARABLE_MEM > '100000' ORDER BY SHARABLE_MEM DESC;找出内容大于100K的sql语句,通过修改和优化sql,使它的执行效率提高,保证数据库中系统的性能。
2、 java pool(java 池):为满足在ORACLE中内嵌JAVA存储过程或其他JAVA程序(例如CORBA中间件)运行时而需要的内存。
3、 large pool(大型池):大型池是一个可选区域。如果创建了大池,那各种进程都会自动使用大池。否则就只能使用共享池中的内存。
既然软解析可以帮助减少sql运行的时间,那么什么情况下oracle会采取软解析呢?
下面通过DQL语句的实验证明软解析的苛刻条件,同时也证明为什么DDL不支持软解析。
实验二 :软解析的苛刻条件
1、实验sql1:
2、实验sql2:
(少了两个空格)
3、测试sql:
实验结果:
结论:可以大胆猜测ORACLE是根据执行SQL语句的哈希值来判断否存在已有的解析树与执行计划,因此同样的sql语句,哪怕是多了一个空格,也会执行硬解析!
软解析会减少cost吗
我们平时可能会使用plsql developer中的f5功能来查看执行计划,而且通过cost来判断sql的消耗,但是这货真的靠谱吗?下面来做一个实验:
实验三:使用软解析之后的cost消耗值步骤一:当前session的硬解析数:
步骤二:用f5测试sql,观察cost值,并且重复运行步骤一的sql,确保使用的是硬解析。
步骤三:重复运行sql,查看f5,并且确定是否使用软解析:
结论:在f5的cost结果中,并没有把生成解析树和执行计划的时间计算在内。