Oracle--使用索引

使用索引
索引用于加快数据定位速度。通过使用索引,可以大大降低I/O次数,从而提高SQL语句的访问性能。
1.单列索引和复合索引
按照索引列的个数,可以将索引划分为单列索引和复合索引俩种类型。
单列索引是指基于单个列所建立的索引,复合索引是指基于两列或多列所建立的索引。
注意,在同一张表上可以建立多个索引,但要求列的组合必须不同,使用以下语句建立的两个索引是合法的:
CREATE INDEX emp_idx1 ON emp (ename,job);
CREATE INDEX emp_idx2 on emp (job,ename);
如上所示,尽管索引emp_idx1和emp_idx2用到了相同的列(ename和job列),但因为顺序不同,所以他们是合法的。
若顺序完全相同,则是不合法的。
2.唯一索引和非唯一索引
按照索引列值的唯一性,可以将索引划分为唯一索引和非唯一索引。
唯一索引是指索引列值不能重复的索引;
非唯一索引是指索引列值可以重复的索引。
注意,当定义主键约束或唯一约束时,Oracle会自动在相应的列上建立唯一索引。
3.使用索引的指导方针
①索引正确的表和列。
当建立和规划所以呢时,必须选择合适的表和列。如果选择了不适合的表和列,那么不仅无法提高查询速度,反而会极大降低DML操作速度。
建立索引的指导方针如下:
    ·索引应该建立在where子句经常引用的表列上。如果在大表上频繁使用某列或某几列作为条件执行检索操作,并且检索的行数低于总行数的15%,
那么应该考虑在这些列上建立索引。
    ·为了提高多表连接的性能,应该在连接列上建立索引。
    ·如果经常需要基于某列或某几列执行排序操作,那么通过在这些列上建立索引,可以加快数据排序的速度。
    ·不要在小表上建立索引。
②限制表的索引个数
索引主要用于加速查询速度,但会降低DML操作的速度。索引越多,DML操作速度将会越慢,尤其会极大影响INSERT操作和DELETE操作的速度。
因此,在规划索引时,必须要仔细权衡查询和DML的需求。
③删除不需要的索引
因为索引会降低DML操作速度,所以应该删除不合理或不需要的索引。在以下情况中,应该考虑删除索引:
    ·删除在小表上建立的索引。如果表很小,那么使用索引不会加快查询速度。
    ·删除查询语句不会引用的索引。如果在某列或几列上建立了索引,但这些列不会再where子句中引用,那么应该删除相关索引。
一、建立索引
建立索引是使用CREATE INDEX命令完成的。一般情况下建立索引是由表的所有者来完成的,
但如果以其他用户身份建立索引,则要求用户必须具有CREATE ANY INDEX系统权限或在相应表上的INDEX对象权限。
建立索引的语法如下:
CREATE [UNIQUE] INDEX index
    ON table(column[,column,...]);
如上所示,index用于指定索引名,table用于指定表名,column用于指定索引列名,UNIQUE选项用于指定建立唯一索引。
1.示例一,建立单列索引
CREATE INDEX i_ename ON emp(ename);
如上所示,当建立了索引i_ename之后,如果在where子句中引用ename列,那么会自动使用该索引。
以下语句会引用该索引:
SELECT sal,job FROM emp where ename='SCOTT';
UPDATE emp SET sal=3000 WHERE ename='SCOTT';
DELETE FROM emp WHERE ename='SCOTT';
2.示例二,建立复合索引
复合索引是指基于多个列所建立的索引。注意,当建立复合索引时,索引列不能超过32个。
CREATE INDEX i_deptno_job ON emp(deptno,job);
以下语句会使用该索引:
SELECT ename,sal FROM emp WHERE deptno=20 AND job='CLERK';
SELECT ename,sal FROM emp WHERE deptno=20;
注意,如果在where子句中使用or谓词引用deptno和job列,或者单独引用job列,那么不会使用索引i_deptno_job。
以下语句不会使用该索引:
SELECT ename,sal FROM emp WHERE deptno=20 OR job='CLERK';
SELECT ename FROM emp WHERE job='CLERK';
3.示例三,建立非唯一索引
非唯一索引是指索引列值可以重复的索引。当建立索引时,如果不指定UNIQUE选项,那么默认情况下会建立非唯一索引。
CREATE INDEX i_job ON emp(job);
4.示例四,建立唯一索引
唯一索引是指索引列值不能重复的索引。当定义主键约束或者唯一约束时,Oracle会自动基于约束列建立唯一索引。
当建立索引时,通过指定UNIQUE选项也可以建立唯一索引。
注意,如果要在特定列上建立唯一索引,那么列数据不能存在重复值。
CREATE UNIQUE INDEX i_dname ON dept(dname);
二、维护索引
当重新组织表之后,会导致其索引转变为无效状态,在这种情况下需要重新建立索引;
当索引不再需要时,应该删除索引。语法如下:
    重建索引:ALTER INDEX index REBUILD[ONLINE];
    删除索引:DROP INDEX index;
1.示例一,重建索引
当执行DELETE操作时,会删除表数据,但在索引上只是进行逻辑删除,其所占用空间不能供其他插入操作使用。
只有当索引块的所有索引入口全部被删除之后,该索引块上的空间才能使用。
如果在索引列上频繁执行UPDATE或DELETE操作,那么应该定期重建索引,以提高其空间利用率。
ALTER INDEX i_job REBUILD;
2.示例二,联机重建索引
当使用REBUILD选项重建索引时,如果其他用户正在表上执行DML操作,那么重建索引将会失败,
并显示错误信息“ORA-00054:资源正忙,但指定以NOWAIT方式获取资源。”
为了最小化DML操作的影响,当重建索引时,可以指定ONLINE选项。
ALTER INDEX department_dname REBUILD ONLINE;
3.示例三,删除索引
索引主要用于提高查询速度,但会降低DML操作的速度。Oracle曾做过一种统计,分别在无索引的表上和存在三个索引的表上执行INSERT操作,前者插入速度要比后者块10倍。
因此,如果索引很少使用,那么应该删除该索引。
DROP INDEX i_job;
三、显示索引信息
1.USER_INDEXES
当建立索引时,Oracle会将索引信息存放到数据字典。
通过查询数字字典视图USER_INDEXS,可以显示当前用户的所有索引。
注意,因为Oracle为该数据字典视图提供了同义词IND,所以可以使用IND取得索引信息。
SELECT index_name,uniqueness,status FROM ind WHERE table_name='EMP';
INDEX_NAME用于表示索引名,uniqueness用于标识索引的唯一性,status用于标识索引状态,table_name用于标识表名。
2.USER_IND_COLUMNS
当建立索引时,Oracle会将索引列的信息写入到数据字典。通过查询数据字典视图USER_IND_COLUMNS,可以显示当前用户索引列的信息。
SELECT column_name,column_position FROM user_ind_columns
WHERE index_name='I_DEPTNO_JOB';
column_name用于标识索引列的名称,column_position用于标识列在索引中的位置,index_name用于标识索引名。

你可能感兴趣的:(Oracle)