Oracle索引梳理系列(三)- Oracle索引種類之反向索引


版權聲明:本文發布於http://www.cnblogs.com/yumiko/,版權由Yumiko_sunny所有,歡迎轉載。轉載時,請在文章明顯位置注明原文鏈接。若在未經作者同意的情況下,將本文內容用於商業用途,將保留追究其法律責任的權利。如果有問題,請以郵箱方式聯系作者(793113046@qq.com)。


 

一 反向索引

1.1 反向索引的定義

  • 反向索引作為B-tree索引的一個分支,主要是在創建索引時,針對索引列的索引鍵值進行字節反轉,進而實現分散存放到不同葉子節點塊的目的。

 

1.2 反向索引針對的問題

  • 使用傳統的B-tree索引,當索引的列是按順序產生時,相應的索引鍵值會基本分布在同一個葉塊中。當用戶對該列進行操作時,難免會發生索引塊的爭用。
  • 使用反向索引,將索引列的鍵值進行反轉,實現順序的鍵值分散到不同的葉塊中,從而減少索引塊的爭用。
  • 例如:鍵值1001、1002、1003,反轉后1001、2001、3001,進而分散到不用的葉子節點塊中。

 

1.3 反向索引應用場景

  • 索引塊成為熱點塊
  • rac環境
    • rac環境下中多節點訪問訪問數據呈現密集且集中的特點,索引熱塊的產生較高。
    • 在范圍檢索不高的rac環境中使用反向索引可有效提高性能。

 

1.4 反向索引的優點與缺點

  • 優點:降低索引葉子塊的爭用問題,提升系統性能。
  • 缺點:對於范圍檢索,例如:between,>,<時,反向索引無法引用,進而導致全表掃面的產生,降低系統性能。

 

1.5 反向索引示例說明

  • -- 創建兩張相同結構的表,內部結構及數據均引用scott用戶下的emp表
    SQL> select count(*) from test01; COUNT(*) ---------- 14
    SQL
    > select count(*) from test02; COUNT(*) ---------- 14 --針對表TEST01的empno列,添加B-tree索引 SQL> create index PK_TEST01 on TEST01(EMPNO); Index created.

    --針對表TEST02的empno列,添加反向索引 SQL
    > create index PK_REV_TEST02 on TEST02(EMPNO) REVERSE; Index created.
    --驗證上面的索引,NORMAL/REV表明為反向索引 SQL
    > select TABLE_NAME,INDEX_NAME,INDEX_TYPE from user_indexes where INDEX_NAME like '%TEST%'; TABLE_NAME INDEX_NAME INDEX_TYPE -------------------- -------------------- -------------------- TEST01 PK_TEST01 NORMAL TEST02 PK_REV_TEST02 NORMAL/REV
    --打開會話追蹤 SQL
    > set autotrace traceonly

    --相同條件查詢,觀察兩表的執行計划 SQL
    > select * from TEST01 where empno=7369;
    Execution
    Plan ---------------------------------------------------------- Plan hash value: 515586510 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 87 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST01 | 1 | 87 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | PK_TEST01 | 1 | | 1 (0)| 00:00:01 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO"=7369) Note ----- - dynamic sampling used for this statement (level=2) Statistics ---------------------------------------------------------- 152 recursive calls 0 db block gets 23 consistent gets 0 physical reads 0 redo size 1025 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL> select * from TEST02 where empno=7369; Execution Plan ---------------------------------------------------------- Plan hash value: 1053012716 --------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 87 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST02 | 1 | 87 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | PK_REV_TEST02 | 1 | | 1 (0)| 00:00:01 | --------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO"=7369) Note ----- - dynamic sampling used for this statement (level=2) Statistics ---------------------------------------------------------- 148 recursive calls 0 db block gets 21 consistent gets 0 physical reads 0 redo size 1025 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed -- 相同范圍條件查詢,觀察兩表的執行計划 SQL> select * from TEST01 where empno between 7350 and 7500; Execution Plan ---------------------------------------------------------- Plan hash value: 515586510 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 174 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST01 | 2 | 174 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | PK_TEST01 | 2 | | 1 (0)| 00:00:01 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO">=7350 AND "EMPNO"<=7500) Note ----- - dynamic sampling used for this statement (level=2) Statistics ---------------------------------------------------------- 9 recursive calls 0 db block gets 10 consistent gets 0 physical reads 0 redo size 1120 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed SQL> select * from TEST02 where empno between 7350 and 7500; Execution Plan ---------------------------------------------------------- Plan hash value: 3294238222 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 174 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| TEST02 | 2 | 174 | 3 (0)| 00:00:01 | ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("EMPNO">=7350 AND "EMPNO"<=7500) Note ----- - dynamic sampling used for this statement (level=2) Statistics ---------------------------------------------------------- 5 recursive calls 0 db block gets 8 consistent gets0 redo size 1112 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed

    通過上面的示例可以看到,當使用between條件進行范圍查詢時,采用反向索引的表,並沒有使用索引,而是采用了全表掃面的方式進行檢索。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM