Oracle 使用表中特定行的索引的原因是什么?

Oracle 使用表中特定行的索引的原因是什么?,oracle,indexing,Oracle,Indexing,在Oracle 11G文档概念中,使用基于函数的索引有以下几种方法: 基于函数的索引对于仅为特定行编制索引也很有用 在桌子上。例如,sh.customers中的cust_valid列 表的值为I或A。要仅为A行编制索引,请 可以编写为任何其他行返回空值的函数 比A排还要多 我只能想象这个用例:通过按条件消除一些行来减小索引的大小。这种可能性有用时还有其他用例吗?让我们看看基于函数的索引: SQL> create table tab1 as select object_name from a

在Oracle 11G文档概念中,使用基于函数的索引有以下几种方法:

基于函数的索引对于仅为特定行编制索引也很有用 在桌子上。例如,sh.customers中的cust_valid列 表的值为I或A。要仅为A行编制索引,请 可以编写为任何其他行返回空值的函数 比A排还要多


我只能想象这个用例:通过按条件消除一些行来减小索引的大小。这种可能性有用时还有其他用例吗?

让我们看看基于函数的索引:

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
          ...
如您所知,所有对象都有唯一的名称,但oracle必须分析所有181行并执行63个一致的GET(物理或逻辑块读取)

让我们创建一个基于函数的索引:

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个一致的GET


因此,基于函数的索引可以很好地提高应用程序的性能。

例如,对于99.999%的行,已完成的列为Y,您只想查询已完成的列!=那么,在NULLIF(COMPLETED,'Y')上这样一个小索引将查询NULLIF(COMPLETED,'Y')不为NULL的位置,或者NULLIF(COMPLETED,'Y')='N'能够非常快速地对索引进行快速完整扫描的位置。