ITPub博客

首页 > 数据库 > Oracle > 回顾SQL的执行过程

回顾SQL的执行过程

原创 Oracle 作者:gydba 时间:2015-09-09 23:29:05 0 删除 编辑
前几天,在想一个SQL的执行计划时,问了郑隐师兄,结果被反问了。现在看来,看似较难的问题,只要仔细思考都会回到一个很基础的知识点。
SQL的处理阶段:
SQL 的处理阶段会包括:解析、优化、产生行源和执行。当然并不是所有Oracle数据库都会这些处理,这得结合具体的SQL语句。

SQL的第一阶段:解析
      这一阶段会将SQL语句的各个片段,分离到由其他进程处理的数据结构,当Oracle数据库得到应用程序的指示下,就会对下一个语句进行解析,这就意味着减少解析数目的不是Oracle数据库本身,而是应用程序
     当应用程序发出SQL语句时,该应用程序就会向数据库发出一个解析调用,用来准备执行该语句。解析调用会打开或者创建一个游标,其中包含了已分析的SQL语句的处理信息。在解析调用时,Oracle数据库会执行以下检查:
  • 语法检查  :主要是检查SQL语句的语法是否符合标准格式
  • 语义检查  : 语义检查是确定该语句中的对象是否存在
  • 共享池检查 :用于确定是否可以跳过占用大量资源的语句处理过程
  如果前面的检查有错,那么在SQL语句执行之前是不会执行的。当然,并不是所有错误都能在解析过程中所检查到,例如:锁

两个概念:硬解析和软解析
1)硬解析
  如果当前数据库中没有执行过的语句,那么就会生成一个执行代码。这个操作就叫硬解析或者库缓存未命中。
  在硬解析期间,数据库会多次访问库缓存和数据字典缓存。当数据库访问到这些区域时,就会给她们上了个锁,以防止它们的定义不会被修改,当然这个代价就是会增加语句的执行时间,降低并发性。

2)软解析
   如果提交的SQL语句在共享池里语句相同,那么就会利用存在的语句代码,这个过程就叫做软解析或者库缓存命中。


一般情况,软解析比硬解析所要达到的效果会很好,因为数据库可以跳过优化和行源生成的步骤,直接进入到这执行过程。

SQL执行第二阶段:优化

 实际上Oracle数据库对查询的优化,是在统计收集数据的执行信息,这些信息来包括使用行数,数据集大小等,利用这些信息来生产各种可能的执行计划,并为每个计划分配一个成本值,这时候Oracle数据库就会具有最低成本的技术(CBO)

PS:提个问题 为什么DDL永远不会被优化,而DML语句必须执行一次硬解析?


SQL执行的第三阶段:行源生成
 行源生成是数据库的一个软件产生的计划过程,它从优化器收集到已经优化的执行计划,并生成一个查询计划的迭代计划,用于生成结果集。行源生成会生成一个行源树,他是一个行源的集合,是执行计划中的某一步骤返回的行集结果
例如:
SELECT /*+gather_plan_statistics test12*/ T.METER_ID "[dianneng]" FROM MPAC.D_METER T LEFT JOIN (SELECT M.EQUIP_ID,
M.CONC_CODE, ROW_NUMBER() OVER(PARTITION BY EQUIP_ID ORDER BY DETECT_DATE DESC) RN FROM (SELECT
T1.EQUIP_ID,T1.CONC_CODE,T1.DETECT_DATE FROM MPAC.T_DETECT_MET_RSLT T1 UNION ALL SELECT
T2.EQUIP_ID,T2.CONC_CODE,T2.DETECT_DATE FROM MPAC.T_SAMPLING_MET_RSLT T2 UNION ALL SELECT
T3.EQUIP_ID,T3.CONC_CODE,T3.DETECT_DATE FROM MPAC.T_COMPARE_MET_RSLT T3) M) TR ON T.METER_ID = TR.EQUIP_ID AND TR.RN=1
WHERE T.STATUS_CODE = '017' AND T.SORT_CODE='10' AND (TR.CONC_CODE='02' OR TR.CONC_CODE IS NULL) AND T.PR_CODE='1'


Execution Plan
----------------------------------------------------------
Plan hash value: 1888591727


--------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                          |  1687 | 74228 |       | 23874   (1)| 00:04:47 |       |       |
|*  1 |  HASH JOIN OUTER                        |                          |  1687 | 74228 |       | 23874   (1)| 00:04:47 |       |       |
|*  2 |   TABLE ACCESS BY GLOBAL INDEX ROWID    | D_METER                  |  1687 | 30366 |       |   240   (1)| 00:00:03 | ROWID | ROWID |
|*  3 |    INDEX RANGE SCAN                     | IDX_D_METER06048         |  4358 |       |       |     8   (0)| 00:00:01 |       |       |
|*  4 |   VIEW                                  |                          |   572K|    14M|       | 23627   (1)| 00:04:44 |       |       |
|*  5 |    WINDOW SORT PUSHED RANK              |                          |   572K|    12M|    17M| 23627   (1)| 00:04:44 |       |       |
|   6 |     VIEW                                |                          |   572K|    12M|       | 19774   (1)| 00:03:58 |       |       |
|   7 |      UNION-ALL                          |                          |       |       |       |            |          |       |       |
|   8 |       TABLE ACCESS BY GLOBAL INDEX ROWID| T_DETECT_MET_RSLT        |   570K|    10M|       | 16851   (1)| 00:03:23 | ROWID | ROWID |
|*  9 |        INDEX RANGE SCAN                 | IDX_T_DETECT_MET_RSLT_04 |   570K|       |       |  1040   (1)| 00:00:13 |       |       |
|* 10 |       TABLE ACCESS FULL                 | T_SAMPLING_MET_RSLT      |  2052 | 43092 |       |  2903   (1)| 00:00:35 |       |       |
|* 11 |       TABLE ACCESS FULL                 | T_COMPARE_MET_RSLT       |   387 |  7353 |       |    19   (0)| 00:00:01 |       |       |
--------------------------------------------------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   1 - access("T"."METER_ID"="TR"."EQUIP_ID"(+))
   2 - filter("T"."SORT_CODE"='10' AND "T"."PR_CODE"='1')
   3 - access("T"."STATUS_CODE"='017')
   4 - filter("TR"."RN"(+)=1)
   5 - filter(ROW_NUMBER() OVER ( PARTITION BY "EQUIP_ID" ORDER BY INTERNAL_FUNCTION("DETECT_DATE") DESC )<=1)
   9 - access("CONC_CODE"='02')
  10 - filter("CONC_CODE"='02')
  11 - filter("CONC_CODE"='02')




Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         19  consistent gets
          3  physical reads
          0  redo size
        327  bytes sent via SQL*Net to client
        481  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30430420/viewspace-1795904/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-08-24

  • 博文量
    77
  • 访问量
    152154