Давайте посмотрим на функции на основе индексов:
SQL> create table tab1 as select object_name from all_objects;
Table created.
SQL> exec dbms_stats.gather_table_stats(user, 'TAB1');
PL/SQL procedure successfully completed.
SQL> set autotrace traceonly
SQL> select count(*) from tab1 where lower(object_name) = 'all_tables';
Execution Plan
----------------------------------------------------------
Plan hash value: 1117438016
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 19 | 18 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 19 | | |
|* 2 | TABLE ACCESS FULL| TAB1 | 181 | 3439 | 18 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(LOWER("OBJECT_NAME")='all_tables')
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
63 consistent gets
...
Как вы знаете, все объекты имеют уникальные имена, но оракул должен анализировать все 181 строк и выполняет 63 последовательно получает (физический или логический блок читает)
Давайте создадим функцию на основе индекса:
SQL> create index tab1_obj_name_idx on tab1(lower(object_name));
Index created.
SQL> select count(*) from tab1 where lower(object_name) = 'all_tables';
Execution Plan
----------------------------------------------------------
Plan hash value: 707634933
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 17 | 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 17 | | |
|* 2 | INDEX RANGE SCAN| TAB1_OBJ_NAME_IDX | 181 | 3077 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(LOWER("OBJECT_NAME")='all_tables')
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
2 consistent gets
...
Как вы можете увидеть сокращение расходов вниз (от 18 до 1) резко и есть только 2 состоят ent получает.
Таким образом, функциональные индексы могут значительно повысить производительность вашего приложения.
Например, столбец COMPLETED, который равен Y для 99,999% строк, и вы хотите запросить только тех, у кого есть COMPLETED! = Y. Тогда такой небольшой индекс в NULLIF (COMPLETED, 'Y') будет делать запросы на WHERE NULLIF (ЗАВЕРШЕН, «Y») НЕ НУЛЛ или ГДЕ NULLIF (ЗАВЕРШЕН, 'Y') = 'N', способный быстро выполнить FAST FULL сканирование индекса. –