程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> Oracle執行分析詳細

Oracle執行分析詳細

編輯:Oracle教程

我們以下面的一個例子來講解

這裡做個補充:trace的類型一共有以下幾種

 

序號

命令

解釋

1

SET AUTOTRACE OFF

此為默認值,即關閉Autotrace

2

SET AUTOTRACE ON EXPLAIN

只顯示執行計劃

3

SET AUTOTRACE ON STATISTICS

只顯示執行的統計信息

4

SET AUTOTRACE ON

包含2,3兩項內容

5

SET AUTOTRACE TRACEONLY

與ON相似,但不顯示語句的執行結果

 

我喜歡SET AUTOTRACE TRACEONLY,我們以後的例子都是基於這種方式的

 

[sql] view plaincopyprint?
  1. SQL> select * from departments a where a.department_id in (select b.department_id from employees b where b.employee_id=205);
  2. Execution Plan
  3. ---------------------------------------------------------- Plan hash value: 2782876085
  4. ----------------------------------------------------------------------------------------------
  5. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------
  6. | 0 | SELECT STATEMENT | | 1 | 27 | 2 (0)| 00:00:01 | | 1 | NESTED LOOPS | | 1 | 27 | 2 (0)| 00:00:01 |
  7. | 2 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 7 | 1 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 |
  8. | 4 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 27 | 540 | 1 (0)| 00:00:01 | |* 5 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 (0)| 00:00:01 |
  9. ----------------------------------------------------------------------------------------------
  10. Predicate Information (identified by operation id): ---------------------------------------------------
  11. 3 - access("B"."EMPLOYEE_ID"=205)
  12. 5 - access("A"."DEPARTMENT_ID"="B"."DEPARTMENT_ID")
  13. Statistics
  14. ---------------------------------------------------------- 1 recursive calls
  15. 0 db block gets 4 consistent gets
  16. 0 physical reads 0 redo size
  17. 749 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client
  18. 2 SQL*Net roundtrips to/from client 0 sorts (memory)
  19. 0 sorts (disk) 1 rows processed
  20. SQL> select * from departments a where a.department_id in (select b.department_id from employees b where b.employee_id=205);
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2782876085
    
    ----------------------------------------------------------------------------------------------
    | Id  | Operation                    | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |               |     1 |    27 |     2   (0)| 00:00:01 |
    |   1 |  NESTED LOOPS                |               |     1 |    27 |     2   (0)| 00:00:01 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES     |     1 |     7 |     1   (0)| 00:00:01 |
    |*  3 |    INDEX UNIQUE SCAN         | EMP_EMP_ID_PK |     1 |       |     0   (0)| 00:00:01 |
    |   4 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS   |    27 |   540 |     1   (0)| 00:00:01 |
    |*  5 |    INDEX UNIQUE SCAN         | DEPT_ID_PK    |     1 |       |     0   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("B"."EMPLOYEE_ID"=205)
       5 - access("A"."DEPARTMENT_ID"="B"."DEPARTMENT_ID")
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
              4  consistent gets
              0  physical reads
              0  redo size
            749  bytes sent via SQL*Net to client
            492  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
     
    讓我們來一行一行的看:

     

    一、表部分

    1、Plan hash value:

     

    [sql] view plaincopyprint?
    1. Plan hash value: 2782876085
      Plan hash value: 2782876085
      這一行是這一條語句的hash值,我們知道oracle對每條語句產生的執行計劃放在share pool裡面,第一次要經過硬解析,產生hash值。下次再執行該語句時候比較hash值,如果相同就不要執行硬解析。

       

      2、Operation( 操作)

      這裡的東西就多了,就是把sql進行分解,讓我一起看看上的sql,這段sql的第一步是employee_id=25,這裡我們employee_id上面建了主鍵,建主鍵默認創建唯一索引。這裡是用“=”進行限制的,所以走的unique scan方式。其他方式參考Oracle執行計劃 講解(一)內容

      還有一個知識點,就是要知道表鏈接操作,見我的另外一篇文章()

      3、Name(被操作的對象)

      比如上例中的第二行operation(TABLE ACCESS BY INDEX ROWID)這裡的TABLE對象為EMPLOYEES

      4、Row,有的地方也叫Cardinality(用plsqldev裡面解釋計劃窗口)

      這裡是數據查詢的行數,比如說上個例子第4行, departments 這張表就要掃描27行,然後和子查詢(select b.department_id from employees b where b.employee_id=205)的值進行比較。如果使用=(注:大部分時候是不能用=來替換,這裡是特例)就不一樣了。

       

      [sql] view plaincopyprint?
      1. SQL> select * from departments a where a.department_id = (select b.department_id from employees b where b.employee_id=205);
      2. Execution Plan
      3. ---------------------------------------------------------- Plan hash value: 3449260133
      4. -----------------------------------------------------------------------------------------------
      5. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -----------------------------------------------------------------------------------------------
      6. | 0 | SELECT STATEMENT | | 1 | 20 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 20 | 1 (0)| 00:00:01 |
      7. |* 2 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 (0)| 00:00:01 | | 3 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 7 | 1 (0)| 00:00:01 |
      8. |* 4 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | -----------------------------------------------------------------------------------------------
      9. Predicate Information (identified by operation id):
      10. ---------------------------------------------------
      11. 2 - access("A"."DEPARTMENT_ID"= (SELECT /*+ */ "B"."DEPARTMENT_ID" FROM "EMPLOYEES" "B" WHERE "B"."EMPLOYEE_ID"=205))
      12. 4 - access("B"."EMPLOYEE_ID"=205)
      13. Statistics
      14. ---------------------------------------------------------- 0 recursive calls
      15. 0 db block gets 4 consistent gets
      16. 0 physical reads 0 redo size
      17. 749 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client
      18. 2 SQL*Net roundtrips to/from client 0 sorts (memory)
      19. 0 sorts (disk) 1 rows processed
      20. SQL> select * from departments a where a.department_id = (select b.department_id from employees b where b.employee_id=205);
        
        
        Execution Plan
        ----------------------------------------------------------
        Plan hash value: 3449260133
        
        -----------------------------------------------------------------------------------------------
        | Id  | Operation                     | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
        -----------------------------------------------------------------------------------------------
        |   0 | SELECT STATEMENT              |               |     1 |    20 |     2   (0)| 00:00:01 |
        |   1 |  TABLE ACCESS BY INDEX ROWID  | DEPARTMENTS   |     1 |    20 |     1   (0)| 00:00:01 |
        |*  2 |   INDEX UNIQUE SCAN           | DEPT_ID_PK    |     1 |       |     0   (0)| 00:00:01 |
        |   3 |    TABLE ACCESS BY INDEX ROWID| EMPLOYEES     |     1 |     7 |     1   (0)| 00:00:01 |
        |*  4 |     INDEX UNIQUE SCAN         | EMP_EMP_ID_PK |     1 |       |     0   (0)| 00:00:01 |
        -----------------------------------------------------------------------------------------------
        
        Predicate Information (identified by operation id):
        ---------------------------------------------------
        
           2 - access("A"."DEPARTMENT_ID"= (SELECT /*+ */ "B"."DEPARTMENT_ID" FROM "EMPLOYEES"
                      "B" WHERE "B"."EMPLOYEE_ID"=205))
           4 - access("B"."EMPLOYEE_ID"=205)
        
        
        Statistics
        ----------------------------------------------------------
                  0  recursive calls
                  0  db block gets
                  4  consistent gets
                  0  physical reads
                  0  redo size
                749  bytes sent via SQL*Net to client
                492  bytes received via SQL*Net from client
                  2  SQL*Net roundtrips to/from client
                  0  sorts (memory)
                  0  sorts (disk)
                  1  rows processed
         

         

        5、Byte

        掃描的數據的字節數

        6、Cost

        這裡上次講過了,這裡簡單說下吧。

        cost沒有單位,是一個相對值,是sql文以cbo方式解析執行時,供oracle用來評估cbo成本,選擇執行計劃用的。

        公式:Cost=(Single block I/O cost+ Multiblock I/O cost+ CPU cost)/sreadtim

        沒有明確的含義,不過對比時就非常有用了。

        7、Time

        每段執行的時間

         

        二、Predicate Information

        這裡列出的是過濾條件,一共有兩種:

        1、索引(access)

        如上例中的access("B"."EMPLOYEE_ID"=205),這裡使用索引作為過濾條件

        2、非索引(filter),看下面這裡例子

         

        [sql] view plaincopyprint?
        1. SQL> select employee_id from employees c
        2. where c.first_name = 'Steven' 2 3 ;
        3. Execution Plan
        4. ---------------------------------------------------------- Plan hash value: 1445457117
        5. -------------------------------------------------------------------------------
        6. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------
        7. | 0 | SELECT STATEMENT | | 1 | 11 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMPLOYEES | 1 | 11 | 3 (0)| 00:00:01 |
        8. -------------------------------------------------------------------------------
        9. Predicate Information (identified by operation id): ---------------------------------------------------
        10. 1 - filter("C"."FIRST_NAME"='Steven')
        11.  
        12. Statistics ----------------------------------------------------------
        13. 1 recursive calls 0 db block gets
        14. 8 consistent gets 0 physical reads
        15. 0 redo size 574 bytes sent via SQL*Net to client
        16. 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client
        17. 0 sorts (memory) 0 sorts (disk)
        18. 2 rows processed
          SQL> select employee_id
                            from employees c
                           where c.first_name = 'Steven'   2    3  ;
          
          
          Execution Plan
          ----------------------------------------------------------
          Plan hash value: 1445457117
          
          -------------------------------------------------------------------------------
          | Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
          -------------------------------------------------------------------------------
          |   0 | SELECT STATEMENT  |           |     1 |    11 |     3   (0)| 00:00:01 |
          |*  1 |  TABLE ACCESS FULL| EMPLOYEES |     1 |    11 |     3   (0)| 00:00:01 |
          -------------------------------------------------------------------------------
          
          Predicate Information (identified by operation id):
          ---------------------------------------------------
          
             1 - filter("C"."FIRST_NAME"='Steven')
          
          
          Statistics
          ----------------------------------------------------------
                    1  recursive calls
                    0  db block gets
                    8  consistent gets
                    0  physical reads
                    0  redo size
                  574  bytes sent via SQL*Net to client
                  492  bytes received via SQL*Net from client
                    2  SQL*Net roundtrips to/from client
                    0  sorts (memory)
                    0  sorts (disk)
                    2  rows processed
          

          這裡的過濾條件是FIRST_NAME,但是FIRST_NAME沒有建立索引,這個時候使用filter,做標記。

           

          三、Statistics(統計信息)

          這裡是重點要說的,如果看累了,可以去喝口水。O(∩_∩)O~

          AUTOTRACE Statistics列解釋

          序號

          列名

          解釋

          1

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved