基於函式的索引(function-based index,FBI)

pingley發表於2012-04-08
基於函式的索引(function-based index,FBI)
FBI 是非常有用的索引,如果查詢條件基於與FBI相同的函式或者表示式。當查詢條件找到了可用的合適的FBI以後,會忽略使用這些columns 上的非FBI索引。FBI索引既可以是b-tree型別的也可以是bitmap 型別的。FBI可以用來處理null 值,大小寫敏感查詢等問題。
注:以下都使用FBI 代表基於函式的索引,這樣可以讓我少敲幾個字。
為了讓最佳化器能夠使用FBI,在系統會在會話級別必須設定如下的兩個引數。
SQL> show parameter query_rewrite_enabled
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
query_rewrite_enabled                string      TRUE
SQL>  show parameter query_rewrite_integrity
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
query_rewrite_integrity              string      TRUSTED
當在查詢條件中對索引列使用函式或者表示式,oracle資料庫將不會使用該列的索引而是進行全表掃描。在查詢條件中對索引列使用函式或者表示式。
SQL> explain plan for
  2  select employee_id,first_name,last_name
  3  from employees
  4  where employee_id+3=200;
Explained.
SQL>  select * from table (dbms_xplan.display(null,null,'basic'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1445457117
---------------------------------------
| Id  | Operation         | Name      |
---------------------------------------
|   0 | SELECT STATEMENT  |           |
|   1 |  TABLE ACCESS FULL| EMPLOYEES |
---------------------------------------
8 rows selected.
執行該語句的時候不會使用employee_id 上的唯一索引。下面是不使用函式或者表示式的例子。
SQL> explain plan for
  2  select employee_id,first_name,last_name
  3  from employees
  4  where employee_id = 197;
Explained.
SQL>  select * from table (dbms_xplan.display(null,null,'basic'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1833546154
-----------------------------------------------------
| Id  | Operation                   | Name          |
-----------------------------------------------------
|   0 | SELECT STATEMENT            |               |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES     |
|   2 |   INDEX UNIQUE SCAN         | EMP_EMP_ID_PK |
-----------------------------------------------------
9 rows selected.
沒有使用函式或者表示式的語句中,oracle 會使用employee_id 列上的索引。
為了在查詢條件中對列運用了函式或者表示式的時候,任然可以使用該列上的索引可以建立FBI.
先把departments 表中的department_name 轉換成小寫。
update departments 
set department_name = lower(department_name);
在department_name 列上建立一個FBI。
SQL> create index depart_name_idx
  2  on departments(upper(department_name));
Index created.
在查詢條件中使用函式。
SQL> select department_id,department_name,location_id
  2  from departments
  3  where upper(department_name) = 'FINANCE';
DEPARTMENT_ID DEPARTMENT_NAME                LOCATION_ID
------------- ------------------------------ -----------
          100 finance                               1700
SQL> select * from table (dbms_xplan.display(null,null,'basic'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3620482735
-------------------------------------------------------
| Id  | Operation                   | Name            |
-------------------------------------------------------
|   0 | SELECT STATEMENT            |                 |
|   1 |  TABLE ACCESS BY INDEX ROWID| DEPARTMENTS     |
|   2 |   INDEX RANGE SCAN          | DEPART_NAME_IDX |
-------------------------------------------------------
9 rows selected.

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

相關文章