我们都知道在 Oracle 中每条 SQL 语句在执行之前都需要经过解析,这里面又分为软解析和硬解析。在 Oracle 中存在两种类型的 SQL 语句,一类为 DDL 语句 ( 数据定义语言 ) ,他们是从来不会共享使用的,也就是每次执行都需要进行硬解析。还有一类就是 DML 语句 ( 数据操纵语言 ) ,他们会根据情况选择要么进行硬解析,要么进行软解析。

DML:INSERT,UPDATE,DELETE,SELECT

DDL:CREATE,DROP,ALTER

.  SQL 解析过程

Oracle 对此 SQL 将进行几个步骤的处理过程:

1 、语法检查 ( syntax check ) : 检查此 sql 的拼写是否语法。

2 、语义检查 ( semantic check ) : 诸如检查 sql 语句中的访问对象是否存在及该用户是否具备相应的权限。

3 、对 sql 语句进行解析 ( prase ) : 利用内部算法对 sql 进行解析,生成解析树 ( parse tree ) 及执行计划 ( execution plan )

4 、执行 sql ,返回结果 ( execute and return )

2.2 语义检查

语法正确的 SQL 语句在解析的第二个步骤就是判断该 SQL 语句所访问的表及列是否准确?用户是否有权限访问或更改相应的表或列? 比如如下语句:

SQL> select * from emp;

select * from emp

ERROR at line 1:

ORA-00942: table or view does not exist

由于查询用户没有可供访问的 emp 对象,因此该 SQL 语句无法通过语义检查。

2.3 解析 (Parse)

2.3.1 Parse 主要分为三种:

1 Hard Parse ( 硬解析 )

2 Soft Parse ( 软解析 )

3 Soft Soft Parse ( 好像有些资料中并没有将这个算在其中 )

Hard Parse 就是上面提到的对提交的 Sql 完全重新从头进行解析 ( 当在 Shared Pool 中找不到时候将会进行此操作 ) ,总共有一下 5 个执行步骤:

1 :语法分析

2 :权限与对象检查

3 在共享池中检查是否有完全相同的之前完全解析好的 . 如果存在,直接跳过 4 5 ,运行 Sql , 此时算 soft parse .

4 :选择执行计划

5 :产生执行计划

注: 创建解析树、生成执行计划对于 sql 的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。这就是在很多项目中,倡导开发设计人员对功能相同的代码要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。

Soft Parse 就如果是在 Shared Pool 中找到了与之完全相同的 Sql 解析好的结果后会跳过 Hard Parse 中的后面的两个步骤。

Soft Soft Parse 实际上是当设置了 session_cursor_cache 这个参数之后, Cursor 被直接 Cache 在当前 Session PGA 中的,在解析的时候只需要对其语法分析、权限对象分析之后就可以转到 PGA 中查找了,如果发现完全相同的 Cursor ,就可以直接去取结果了,也就就是实现了 Soft Soft Parse.

1 ) 验证 SQL 语句是否完全一致。

在这个步骤中, Oracle 将会对传递进来的 SQL 语句使用 HASH 函数运算得出 HASH 值,再与共享池中现有语句的 HASH 值进行比较看是否一一对应。现有数据库中 SQL 语句的 HASH 值我们可以通过访问 v$sql v$sqlarea v$sqltext 等数据字典中的 HASH_VALUE 列查询得出。

如果 SQL 语句的 HASH 值一致,那么 ORACLE 事实上还需要对 SQL 语句的语义进行再次检测,以决定是否一致。那么为什么 Oracle 需要再次对语句文本进行检测呢?不是 SQL 语句的 HASH 值已经对应上了?事实上就算是 SQL 语句的 HASH 值已经对应上了,并不能说明这两条 SQL 语句就已经可以共享了。

例如: 假如用户 SYS 有自己的一张表 EMP ,他要执行查询语句: select * from emp ; 用户 SYSTEM 也有一张 EMP 表,同样要查询 select * from emp ;这样他们两条语句在文本上是一模一样的,他们的 HASH 值也会一样,但是由于涉及到查询的相关表不一样,他们事实上是无法共享的 .

SQL> conn / as sysdba

SQL> show user

USER "SYS"

SQL>  create table emp ( x int ) ;

表已创建。

SQL> select * from emp;

SQL> conn system/admin;

SQL>  create table emp ( x int );

表已创建。

SQL> select * from emp;

SQL> select address,hash_value, executions, sql_text from v$sql where upper(sql_text) like 'SELECT * FROM EMP%';

ADDRESS      HASH_VALUE EXECUTIONS SQL_TEXT

----------------------- ---------------------------------------------------------

2769AE64    1745700775     1 select * from emp

2769AE64    1745700775     1 select * from emp

2 rows selected.

从结果可以 看到这 2 个查询的语句文本和 HASH 值都是一样的,但是由于查询的对象不同,是无法共享的,不同情况的语句还是需要硬解析的。因此在检查共享池共同 SQL 语句的时候,是需要根据具体情况而定的。

可以进一步查询 v$sql_shared_cursor 以得知 SQL 为何不能共享的原因:

SQL> select address,auth_check_mismatch,translation_mismatch , optimizer_mismatch

from v$sql_shared_cursor where address in (

select address from v$sql where upper(sql_text) like 'SELECT * FROM EMP%' )

ADDRESS     A T O

---------------- ----- -- --

2769AE64     N N N

2769AE64     Y Y N

TRANSLATION_MISMATCH 表示 SQL 游标涉及到的数据对象是不同的;

AUTH_CHECK_MISMATCH 表示对同样一条 SQL 语句转换是不匹配的。

optimizer_mismatch 表示会话的优化器环境是不同的。

2 ) 验证 SQL 语句执行环境是否相同

比如同样一条 SQL 语句,一个查询会话加了 /*+ first_rows */ HINT ,另外一个用户加 /*+ all_rows */ HINT ,他们就会产生不同的执行计划,尽管他们是查询同样的数据。

通过如上检查以后,如果 SQL 语句是一致的,那么就会重用原有 SQL 语句的执行计划和优化方案,也就是我们通常所说的软解析。如果 SQL 语句没有找到同样的副本,那么就需要进行硬解析了。

Oracle 根据提交的 SQL 语句再查询相应的数据对象是否有统计信息。如果有统计信息的话,那么 CBO 将会使用这些统计信息产生所有可能的执行计划 ( 可能多达成千上万个 ) 和相应的 Cost ,最终选择 Cost 最低的那个执行计划。如果查询的数据对象无统计信息,则按 RBO 的默认规则选择相应的执行计划。这个步骤也是解析中最耗费资源的,因此我们应该极力避免硬解析的产生。至此,解析的步骤已经全部完成, Oracle 将会根据解析产生的执行计划执行 SQL 语句和提取相应的数据。

2. 4 执行 sql ,返回结果 ( execute and return )

使用了 Bind Var 能提高性能主要是因为这样做可以尽量避免不必要的硬分析 ( Hard Parse ) 而节约了时间,同时节约了大量的 CPU 资源。

当一个 Client 提交一条 Sql Oracle 后, Oracle 首先会对其进行解析 ( Parse ) ,然后将解析结果提交给优化器 ( Optimiser ) 来进行优化而取得 Oracle 认为的最优的 Query Plan ,然后再按照这个最优的 Plan 来执行这个 Sql 语句 ( 当然在这之中如果只需要软解析的话会少部分步骤 )

但是,当 Oracle 接到 Client 提交的 Sql 后会首先在共享池 ( Shared Pool ) 里面去查找是否有之前已经解析好的与刚接到的这一个 Sql 完全相同的 Sql ( 注意这里说的是完全相同,既要求语句上的字符级别的完全相同,又要求涉及的对象也必须完全相同 ) 。当发现有相同的以后解析器就不再对新的 Sql 在此解析而直接用之前解析好的结果了。这里就节约了解析时间以及解析时候消耗的 CPU 资源。尤其是在 OLTP 中运行着的大量的短小 Sql ,效果就会比较明显了。因为一条两条 Sql 的时间可能不会有多少感觉,但是当量大了以后就会有比较明显的感觉了。

注:整理自网络

------------------------------------------------------------------------------
QQ: 492913789
Email: ahdba@qq.com
Blog: http://www.cndba.cn/dave
网上资源: http://tianlesoftware.download.csdn.net
相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx
DBA1 群:62697716(满);   DBA2 群:62697977(满)   DBA3 群:62697850(满)
DBA 超级群:63306533(满);  DBA4 群: 83829929  DBA5群: 142216823
DBA6 群:158654907  聊天 群:40132017   聊天2群:69087192
--加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请

1.更改参数cursor_sharing参数cursor_sharing决定了何种类型的 SQL 能够使用相同的 SQL areaCURSOR_SHARING = { SIMILAR | EXACT | FORCE }EXACT --只有当发布的 SQL 语句与缓存中的语句完全相同时才用已有的执行计划。FORCE --如果 SQL 语句是字面量,则迫使Optimizer始终使用已有的执行计划,无论已有的执行计划... a.EXECUTIONS "总执行次数", nvl(a.ELAPSED_TIME, 0) / 1000 / 1000 "总耗时(秒)", (nvl(a.ELAPSED_TIME, 0) / nvl(decode(a.EXECUTIONS, 0, 1, a.EXECUTIONS), 1)) / 1000 /. ORACLE 解析 分析前言 ORACLE 解析 解析 AWR报告中的 解析 通过 ORACLE 视图判断 解析 工作中 ORACLE 使用的越多,发现对 ORACLE 了解的越少。用到现在发现对于 ORACLE 什么都不会了。悲剧。今天看AWR报告的时候看到了 解析 ,顺便就把相关的知识点重新学习了一遍。 ORACLE 解析 解析 ORACLE 中,当执行一条新的 SQL 时,大致步骤如下: 1、语法检查,如果... SQL 任务是ODPS中使用最频繁的一类作业,大部分用户开始使用ODPS时要做的第一件事情就是学习怎么写ODPS的 SQL 。ODPS SQL 是一种非常灵活的语言,兼容大部分的 SQL 92规范,也对大规模计算场景做了一些特别的定制。有些用户写出的 SQL 让人看了之后茅塞顿开的感觉,也有一些神级用户经常写一些1000多行的 SQL Oracle 解析 解析 提到 解析 (soft prase)和 解析 (hard prase),就不能不说一下 Oracle sql 的处理过程。当你发出一条 sql 语句交付 Oracle ,在执行和获取结果前, Oracle 对此 sql 将进行几个步骤的处理过程: 1、语法检查(syntax check) 检查此 sql 的拼写是否语法。 2、语义检查(semantic check) 诸如检查 sql 语句中的访问对... 简单的说一个 sql 语句是按照如下的顺序 解析 的: 1. FROMFROM后面的表标识了这条语句要查询的数据源。和一些子句如,(1-J1)笛卡尔积,(1-J2)ON过滤,(1-J3)添加外部列,所要应用的对象。FROM过... 首先要知道,判断是 解析 还是 解析 的依据在于sga中的 share cursor 的缓存情况,而判断是不是 解析 的依据在于pga中的 session cursor是否可以重用, 解析 还是 解析 :我们知道 oracle SGA中包含share pool ,而share pool是由库缓存区(library cache)和数据字典缓存区(data dict cache)组成。数据字典缓存区:缓存最近执行... SGA(共享池)有一块区域 称为库高速缓存,该区域用于存放 Oracle 以执行过的 SQL 语句,可以通过v$ sql 视图来查看该区域所存放的语句。 在 Oracle 中每执行一句语句必然会被 解析 并存入库高速缓存中, 解析 包括验证语法、验证提及对象,验证用户权限。如果通过,就会检查库高速缓存确定是否执行过,如果是, Oracle 将取回其信息并重用,这种情况被称为 解析 。如果不是, Oracle 将执行所有工作来生成执行 作者:一帅 SQL 任务是ODPS中使用最频繁的一类作业,大部分用户开始使用ODPS时要做的第一件事情就是学习怎么写ODPS的 SQL 。ODPS SQL 是一种非常灵活的语言,兼容大部分的 SQL 92规范,也对大规模计算场景做了一些特别的定制。有些用户写出的 SQL 让人看了之后茅塞顿开的... 我们都知道在 Oracle 中每条 SQL 语句在执行之前都需要经过 解析 ,这里面又分为 解析 解析 。在 Oracle 中存在两种类型的 SQL 语句,一类为DDL语句(数据定义语言),他们是从来不会共享使用的,也就是每次执行都需要进行 解析 。还有一类就是DML语句(数据操纵语言),他们会根据情况选择要么进行 解析 ,要么进行 解析 。DML:INSERT,UPDATE,DELETE,SELECTDDL:CREATE...