帶您了解Oracle FBI索引
Oracle FBI索引是Oracle8i的新特性,下面就為您詳細介紹Oracle FBI索引的概念及使用,如果您對Oracle FBI索引方面感興趣的話,不妨一看。
Oracle8i的很重要的一個新特性就是增加了function-based index這種索引類型(后面簡稱為FBI)。有了這個特性后,Oracle DBA就可以在索引中使用函數或者表達式了。這些函數可以使Oracle自己的函數,也可以使用戶自己的PL/SQL函數等。
DBA在SQL語句調優的過程中遇到的一個很常見的問題就是,如何優化那些在WHERE子句中使用了函數的語句。因為在以前,在WHERE子句中使用函數會使在這個表上創建的索引沒法利用,從而難以提高這個語句的性能。
例子:
使用基于成本的優化器,索引為標準的B樹索引,建立在SURNAME列上。
- SQL>create index non_fbi on sale_contacts (surname);
- SQL>analyze index non_fbi compute statistics;
- SQL>:analyze table sale_contacts compute statistics;
- SQL>SELECT count(*) FROM sale_contacts
- WHERE UPPER(surname) = 'ELLISON';
- Execution Plan
- ----------------------------------------------------------
- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=17)
- 1 0 SORT (AGGREGATE)
- 2 1 TABLE ACCESS (FULL) OF 'SALES_CONTACTS' (Cost=3 Card=16 Bytes=272)
從SQL*PLUS的autotrace產生的執行路徑可以看到,雖然我們在WHERE子句中用到的SURNAME列上創建了索引,但是仍然執行的是全表掃描。如果這張表很大的話,這回消耗大量的時間。
現在我們試著建立一個Oracle FBI索引:
- SQL>create index fbi on sale_contacts (UPPER(surname));
- SQL>analyze index fbi compute statistics;
- SQL>analyze table sale_contacts compute statistics;
- SQL>SELECT count(*) FROM sale_contacts WHERE UPPER(surname) = 'ELLISON';
- Execution Plan
- ----------------------------------------------------------
- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=17)
- 1 0 SORT (AGGREGATE)
- 2 1 INDEX (RANGE SCAN) OF 'FBI' (NON-UNIQUE) (Cost=2 Card=381 Bytes=6477)
從SQL*Plus返回的執行計劃我們可以看到,這次,Oracle對表不再全表掃描,而是先掃描索引,因為優化器可以知道FBI索引得存在。
使用Oracle FBI索引所能夠帶來的性能提升取決于表的大小、表中重復記錄的量、在WHERE子句中使用的列等因素。
有一點需要清楚,Oracle FBI索引并不真正在索引里邊存儲了表達式的結果,而是使用了一個"表達樹"(expression tree)。
【編輯推薦】