重庆思庄Oracle、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1257|回复: 0
打印 上一主题 下一主题

[Oracle] 如何看懂ORACLE的执行计划

[复制链接]
跳转到指定楼层
楼主
发表于 2023-9-17 12:37:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、看懂Oracle执行计划
上面已经介绍了如何查看执行计划,现在简单介绍一下一些基本方法和相关理论知识

1.1 查看explain
找一条比较复杂的SQL:

SQL_ID  4qfq3t2ukm0y1, child number 0
-------------------------------------
SELECT /*+ monitor*/ A.USER_CODE, A.FULL_NAME, A.USER_PWD, C.UNIT_CODE,
C.UNIT_NAME FROM BASE_USER A LEFT JOIN (SELECT UR.USER_CODE,
UR.UNIT_CODE FROM APPR_USER_ROLE UR WHERE UR.USER_ROLE < 10) B ON
A.USER_CODE = B.USER_CODE LEFT JOIN LZCITY_APPROVE_UNIT_INFO C ON
B.UNIT_CODE = C.UNIT_CODE WHERE C.UNIT_CODE ='15803'

Plan hash value: 3288287052

------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                        | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                             |      1 |        |     3 (100)|          |     16 |00:00:00.01 |      38 |
|   1 |  NESTED LOOPS                  |                             |      1 |      1 |     3   (0)| 00:00:01 |     16 |00:00:00.01 |      38 |
|   2 |   NESTED LOOPS                 |                             |      1 |      1 |     3   (0)| 00:00:01 |     16 |00:00:00.01 |      22 |
|   3 |    NESTED LOOPS                |                             |      1 |      1 |     2   (0)| 00:00:01 |     16 |00:00:00.01 |       5 |
|   4 |     TABLE ACCESS BY INDEX ROWID| LZCITY_APPROVE_UNIT_INFO    |      1 |      1 |     1   (0)| 00:00:01 |      1 |00:00:00.01 |       3 |
|*  5 |      INDEX UNIQUE SCAN         | PK_LZCITY_APPROVE_UNIT_INFO |      1 |      1 |     0   (0)|          |      1 |00:00:00.01 |       2 |
|*  6 |     INDEX RANGE SCAN           | PK_APPR_USER_ROLE           |      1 |      1 |     1   (0)| 00:00:01 |     16 |00:00:00.01 |       2 |
|*  7 |    INDEX UNIQUE SCAN           | PK_BASE_USER                |     16 |      1 |     0   (0)|          |     16 |00:00:00.01 |      17 |
|   8 |   TABLE ACCESS BY INDEX ROWID  | BASE_USER                   |     16 |      1 |     1   (0)| 00:00:01 |     16 |00:00:00.01 |      16 |
------------------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$E3445A69
   4 - SEL$E3445A69 / C@SEL$4
   5 - SEL$E3445A69 / C@SEL$4
   6 - SEL$E3445A69 / UR@SEL$2
   7 - SEL$E3445A69 / A@SEL$3
   8 - SEL$E3445A69 / A@SEL$3

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('11.2.0.4')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$E3445A69")
      MERGE(@"SEL$2")
      OUTLINE(@"SEL$A2E96217")
      OUTER_JOIN_TO_INNER(@"SEL$E9F4A6F9" "B"@"SEL$1")
      OUTER_JOIN_TO_INNER(@"SEL$E9F4A6F9" "C"@"SEL$4")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SEL$E9F4A6F9")
      MERGE(@"SEL$80808B20")
      OUTLINE(@"SEL$6")
      OUTLINE(@"SEL$80808B20")
      MERGE(@"SEL$4")
      MERGE(@"SEL$F1D6E378")
      OUTLINE(@"SEL$5")
      OUTLINE(@"SEL$4")
      OUTLINE(@"SEL$F1D6E378")
      MERGE(@"SEL$1")
      OUTLINE(@"SEL$3")
      OUTLINE(@"SEL$1")
      INDEX_RS_ASC(@"SEL$E3445A69" "C"@"SEL$4" ("LZCITY_APPROVE_UNIT_INFO"."UNIT_CODE"))
      INDEX(@"SEL$E3445A69" "UR"@"SEL$2" ("APPR_USER_ROLE"."UNIT_CODE" "APPR_USER_ROLE"."USER_CODE" "APPR_USER_ROLE"."AREA_SEQ"
              "APPR_USER_ROLE"."USER_ROLE"))
      INDEX(@"SEL$E3445A69" "A"@"SEL$3" ("BASE_USER"."USER_CODE"))
      LEADING(@"SEL$E3445A69" "C"@"SEL$4" "UR"@"SEL$2" "A"@"SEL$3")
      USE_NL(@"SEL$E3445A69" "UR"@"SEL$2")
      USE_NL(@"SEL$E3445A69" "A"@"SEL$3")
      NLJ_BATCHING(@"SEL$E3445A69" "A"@"SEL$3")
      END_OUTLINE_DATA
  */

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

   5 - access("C"."UNIT_CODE"='15803')
   6 - access("UR"."UNIT_CODE"='15803' AND "UR"."USER_ROLE"<10)
       filter("UR"."USER_ROLE"<10)
   7 - access("A"."USER_CODE"="UR"."USER_CODE")


1.2 explain执行顺序
所以不管是用F5方式还是set statistics_level=ALL方式,都有Operation参数,Operation表示sql执行过程,查看怎么执行的,有两个规则:

根据Operation缩进判断,缩进最多的最先执行;
Operation缩进相同时,最上面的是最先执行的;
如图执行计划,根据规则,可以得出执行顺序:INDEX UNIQUE SCAN->TABLE ACCESS BY INDEX ROWID->INDEX RANGE SCAN ->NESTED LOOPS ->INDEX UNIQUE SCAN->NESTED LOOPS ->TABLE ACCESS BY INDEX ROWID->NESTED LOOPS-> SELECT STATEMENT

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2024-11-25 07:31 , Processed in 0.119712 second(s), 24 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表