關於Oracle 9i 跳躍式索引掃描(Index Skip Scan)的小測試 (轉)

amyz發表於2007-08-16
關於Oracle 9i 跳躍式索引掃描(Index Skip Scan)的小測試 (轉)[@more@]


在9i中我們知道能夠使用跳躍式掃描(Index SkScan).然而,能利用跳躍式索引掃描的情況其實是有些限制的.

從Oracle的文件中我們可以找到這樣的話:

Index Skip Scans
Index skip scans improve index scans by nonprefix columns.
Often, scanning index blocks is faster than scanning table data blocks.
Skip scanning lets a composite index be split logically into smaller subindexes.
In skip scanning, the initial column of the composite index is not specified in the query.
In other s, it is skipped.

The number of logical subindexes is detened by the number of distinct values in the initial column.
Skip scanning is advantageous if there are few distinct values in the leading column of the composite
index and many distinct values in the nonleading key of the index.

也可以這樣說,器根據索引中的前導列(索引到的第一列)的唯一值的數量決定是否使用Skip Scan.

我們首先做個測試:

> CREATE TABLE test AS
  2  ROWNUM a,ROWNUM-1 b ,ROWNUM-2 c,ROWNUM-3 d,ROWNUM-4 e
  3  FROM all_s
  4  /

SQL> SELECT DISTINCT COUNT (a) FROM test;

  COUNT(A)
----------
  28251

表已建立。

SQL>
SQL> CREATE INDEX test_idx ON test(a,b,c)
  2  /

索引已建立。

SQL> ANALYZE TABLE test COMPUTE STATISTICS
  2  FOR TABLE
  3  FOR ALL INDEXES
  4  FOR ALL INDEXED COLUMNS
  5  /

表已分析。

SQL> SET autotrace traceonly explain
SQL> SELECT *  FROM test WHERE b = 99
  2  /

Execution Plan
----------------------------------------------------------
  0  SELECT STATEMENT Optimizer=CHOOSE (Cost=36 Card=1 Bytes=26)
  1  0 TABLE ACCESS (FULL) OF 'TEST' (Cost=36 Card=1 Bytes=26)

--可見這裡CBO選擇了全表掃描.

--我們接著做另一個測試:

SQL> drop table test;

表已丟棄。

SQL> CREATE TABLE test
  2  AS
  3  SELECT DECODE(MOD(ROWNUM,2), 0, '1', '2' ) a,
  4  ROWNUM-1 b,
  5  ROWNUM-2 c,
  6  ROWNUM-3 d,
  7  ROWNUM-4 e
  8  FROM all_objects
  9  /

表已建立。

SQL> set autotrace off
SQL> select distinct a from test;

A
--
1
2

--A列只有兩個唯一值

SQL> CREATE INDEX test_idx ON test(a,b,c)
  2  /

索引已建立。


SQL> ANALYZE TABLE test COMPUTE STATISTICS
  2  FOR TABLE
  3  FOR ALL INDEXES
  4  FOR ALL INDEXED COLUMNS
  5  /

表已分析。

SQL> set autotrace traceonly explain
SQL> SELECT *  FROM test WHERE b = 99
  2  /

Execution Plan
----------------------------------------------------------
  0  SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=1 Bytes=24)
  1  0  TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=4 Card=1 Bytes=24)
  2  1  INDEX (SKIP SCAN) OF 'TEST_IDX' (NON-UNIQUE) (Cost=3 Card=1)

 

Oracle的最佳化器(這裡指的是CBO)能對查詢應用Index Skip Scans至少要有幾個條件:

1 最佳化器認為是合適的.
2 索引中的前導列的唯一值的數量能滿足一定的條件.
3 最佳化器要知道前導列的值分佈(透過分析/統計表得到)
4 合適的SQL語句
......


更多資訊請參考:

.NET/showthread.?threadid=85948">http://www.itpub.net/showthread.php?threadid=85948

http://www.itpub.net/showthread.php?s=&postid=985602#post985602

OracleDatabase Performance Tuning Gu and Reference Release 2 (9.2)
Part Number A96533-02

感謝參加討論的各位高手.


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

相關文章