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)。
【编辑推荐】