【優化】INDEX FULL SCAN (MIN/MAX)訪問路徑

secooler發表於2009-11-26
Oracle對單獨使用max或min函式時給出了一種非常高效的訪問路徑,就是“INDEX FULL SCAN (MIN/MAX)”,該方法可以避免索引的全部讀取,進一步提高資料結果的獲取效率。
通過這個實驗簡單記錄一下。

1.建立測試表
我們先建立一個包含一百萬條記錄的表t,在t表的第一個欄位x上有主鍵。
sec@ora10g> select count(*) from t;

  COUNT(*)
----------
   1000000

2.開啟autotrace功能檢視一下max函式對應的執行計劃
sec@ora10g> set autotrace on
sec@ora10g> select max(x) from t;

    MAX(X)
----------
   1000000

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 1172912737

-----------------------------------------------------------------------------------
| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |     1 |     5 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE            |      |     1 |     5 |            |          |
|   2 |   INDEX FULL SCAN (MIN/MAX)| PK_T |   994K|  4858K|     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        513  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


3.“INDEX FULL SCAN (MIN/MAX)”訪問路徑
此處SQL優化器不但可以識別到使用索引掃描可以提速,而且針對特定的max函式(或min函式)使用特有的“INDEX FULL SCAN (MIN/MAX)”訪問路徑來快速獲取最大值(或最小值)。
使用這種訪問路徑獲得最大值時,可以不必將所有的索引內容預讀一遍,而是從索引儘量靠後的記錄開始讀,這樣便可以更加快速地獲得最大值。

4.如果max和min函式同時使用會有什麼的執行計劃呢?
sec@ora10g> select min(x), max(x) from t;

    MIN(X)     MAX(X)
---------- ----------
         1    1000000

Elapsed: 00:00:00.21

Execution Plan
----------------------------------------------------------
Plan hash value: 949213647

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |     1 |     5 |   466   (2)| 00:00:06 |
|   1 |  SORT AGGREGATE       |      |     1 |     5 |            |          |
|   2 |   INDEX FAST FULL SCAN| PK_T |   994K|  4858K|   466   (2)| 00:00:06 |
------------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2102  consistent gets
          0  physical reads
          0  redo size
        580  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


通過上面的執行計劃可見,min(x)和max(x)函式同時使用時是無法使用“INDEX FULL SCAN (MIN/MAX)”的。原因很簡單,同一張表既想得到最小值又想得到最大值只能將所有的資料預讀一遍才知道。此時SQL優化器給出的方法是“INDEX FAST FULL SCAN”。也就是說僅用索引本身就可以回答這個問題,無需訪問表t,這也是一種高效獲得資料的方法,類似於將原來的大表重新構造了一個以索引形式存在的“小表”。

5.小結
Oracle在常用查詢上給出的執行計劃有助於高效的完成任務。
Oracle細節之處很精彩。

secooler
09.11.26

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-620679/,如需轉載,請註明出處,否則將追究法律責任。

相關文章