§3.6.1 基于函数的索引
基于函数的索引就是存储预先计算好的函数或表达式值的索引。这些表达式可以是算术运算表达式、SQL或 PL/SQL函数、C调用等。值得注意的是,一般用户要创建函数索引,必须具有GLOBAL QUERY REWRITE和CREATE ANY INDEX权限。否则不能创建函数索引,看下面例子:
例1:为EMP表的ename 列建立大写转换函数的索引idx :
CREATE INDEX idx ON emp ( UPPER(ename));
这样就可以在查询语句来使用:
SELECT * FROM EMP WHERE UPPER(ename) LIKE ‘JOH%’;
例2:为emp 的工资和奖金之和建立索引:
1) 查看emp 的表结构:
SQL> desc emp
Name Null? Type
----------------------------------------- -------- ------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
2)没有授权就创建函数索引的提示:
SQL> create index sal_comm on emp ( (sal+comm)*12, sal,comm)
2 tablespace users storage(initial 64k next 64k pctincrease 0);
create index sal_comm on emp ( (sal+comm)*12, sal,comm)
*
ERROR at line 1:
ORA-01031: insufficient privileges
3) 连接到DBA帐户并授权:
SQL> connect sys/sys@ora816
Connected.
SQL> grant GLOBAL QUERY REWRITE to scott;
Grant succeeded.
SQL> grant CREATE ANY INDEX to scott;
Grant succeeded.
4)在连接到scott帐户,创建基于函数的索引:
SQL> connect scott/tiger@ora816
Connected.
SQL> create index sal_comm on emp ( (sal+comm)*12, sal,comm)
2 tablespace users storage(initial 64k next 64k pctincrease 0);
Index created.
1)在查询中使用函数索引:
SQL> select ename,sal,comm from emp where (sal+comm)*12 >5000;
ENAME SAL COMM
---------------------- ---------------- ----------------
ALLEN 1600 300
WARD 1250 500
MARTIN 1250 1400
TURNER 1500 0
赵元杰 1234.5 54321
§3.6.2 反向键索引
反向键索引通过反向键保持索引的所有叶子键上的插入分布。有时,可用反向键索引来避免不平衡的索引。对于反向键索引可以进行下面操作:
l 通过在ALTER INDEX命令后加REBUILD NOREVERSE或REBUILD REVERSE子句来使索引边为反向键索引或普通索引;
l 采用范围扫描的查询不能使用反向键索引;
l 位图索引不能反向;
l 索引编排表不能反向。
例1:创建一个反向键索引:
CREATE INDEX i ON t (a,b,c) REVERSE;
SQL>select * from user_ind_columns where index_name=upper('&index_name');
PS:
查看某表的约束条件
SQL>select constraint_name, constraint_type,search_condition, r_constraint_name
from user_constraints where table_name = upper('&table_name');
SQL>select c.constraint_name,c.constraint_type,cc.column_name
from user_constraints c,user_cons_columns cc
where c.owner = upper('&table_owner') and c.table_name = upper('&table_name')
and c.owner = cc.owner and c.constraint_name = cc.constraint_name
order by cc.position;