跳躍式索引(Skip Scan Index)淺析 - 轉

ningzi82發表於2010-10-19
在Oracle9i中,有一個新的特性:跳躍式索引(Skip Scan Index)。當表有一個複合索引,而在查詢中有除了索引中第一列的其他列作為條件,並且最佳化器模式為CBO,這時候查詢計劃就有可能使用到SS。此外, 還可以透過使用提示index_ss(CBO下)來強制使用SS。

  在Oracle9i 中,有一個新的特性:跳躍式索引(Skip Scan Index)。當表有一個複合索引,而在查詢中有除了索引中第一列的其他列作為條件,並且最佳化器模式為CBO,這時候查詢計劃就有可能使用到SS。此外, 還可以透過使用提示index_ss(CBO下)來強制使用SS。

  舉例:


  SQL> create test1 (a number, b char(10), c varchar2(10));
  Table created.
  SQL> create index test_idx1 on test1(a, b);
  Index created.
  SQL> autotrace on
  SQL> select /*+index_ss(test1 test_idx1)*/* from test1 a
  2 where b ='a';
  no rows selected
  Execution Plan
  0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 =1 Bytes=32)
  1 0 TABLE (BY INDEX ROWID) OF 'TEST1' (Cost=2 Card=1 Bytes=32)
  2 1 INDEX (SKIP SCAN) OF 'TEST_IDX1' (NON-UNIQUE)

  但並不是任何情況下都會使用到SS。在Oracle的官方文件中,除了提到需要CBO,並且對錶進行過分析外,還需要保證第一列的distinct value非常小。這一段是從官方文件上摘取的關於SS的一段解釋:

  Index skip scans improve index scans by nonprefix columns since it is often faster to scan index blocks than scanning table blocks.

  In this case a composite index is split logically into smaller subindexes. The number of logical subindexes depends on the of the initial column. Hence it is now possible to use the index even if the leading column is not used in a where clause.

  Oracle並沒有公佈過關於SS更多的內部技術細節。但注意上面的這句話:In this case a composite index is split logically into smaller subindexes. The number of logical subindexes depends on the cardinality of the initial column.即Oralce會對複合索引進行邏輯劃分,分成多個子索引。可以這樣理解,Oracle將索引從邏輯上劃分為a.num_distinct 個子索引,每次對一個子索引進行掃描。因此SS的索引掃描成本為a.num_distinct.

  下面做一些試驗,看看在什麼情況下Oracle採用SS.

  首先要保證使用SS的幾個必要條件:

  · Optimizer為CBO

  · 相關表要有正確的統計資料

  · Oracle DB版本為9i以上

  下面就是一個使用到SS的特殊條件:第一列的distinct num要足夠小。小到什麼程度呢?

  還是以上面的表為例(省略中間的麻煩步驟,取兩個臨界值做實驗):

[@more@]具體見:

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

相關文章