暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ROWID

原创 手机用户3127 2022-06-20
219

索引是由Oracle维护的可选结构,为数据提供快速的访问。准确地判断在什么地方需要使用索引是困难的,使用索引有利于调节检索速度。 当建立一个索引时,必须指定用于跟踪的表名以及一个或多个表列。一旦建立了索引,在用户表中建立、更改和删除数据库时, Oracle就自动地维护索引。创建索引时,下列准则将帮助用户做出决定:

  1) 索引应该在SQL语句的"where"或"and"部分涉及的表列(也称谓词)被建立。假如

  personnel表的"firstname"表列作为查询结果显示,而不是作为谓词部分,则不论其值是什么,该表列不会被索引。

  2)用户应该索引具有一定范围的表列,索引时有一个大致的原则:如果表中列的值占该表中行的2 0 %以内,这个表列就可以作为候选索引表列。假设一个表有36 000行且表中一个表列的值平均分布(大约每12000行),那么该表列不适合于一个索引。然而,如果同一个表中的其他表列中列值的行在1 0 0 0~1 5 0 0之间(占3 %~4 % ),则该表列可用作索引。

  3)如果在S Q L语句谓词中多个表列被一起连续引用,则应该考虑将这些表列一起放在一个索引内, O r a c l e将维护单个表列的索引(建立在单一表列上)或复合索引(建立在多个表列上)。复合索引称并置索引。

  1 主关键字的约束

  关系数据库理论指出,在表中能唯一标识表的每个数据行的一个或多个表列是对象的主关键字。由于数据字典中定义的主关键字能确保表中数据行之间的唯一性,因此,在O r a c l e 8 i数据库中建立表索引关键字有助于应用调节。另外,这也减轻了开发者为了实现唯一性检查,而需要各自编程的要求。

  提示使用主关键字索引条目比不使用主关键字索引检索得快。

  假设表p e r s o n把它的i d表列作为主关键字,用下列代码设置约束:

alter table person add constraint person_pk primary key (id) using index storage (initial 1m next 1m

pctincrease 0) tablespace prd_indexes ;

  处理下列S Q L语句时:

select last_name ,first_name ,salary from person where id = 289 ;

  在查找一个已确定的“ i d”表列值时, O r a c l e将直接找到p e r s o n _ p k。如果其未找到正确的索引条目,O r a c l e知道该行不存在。主关键字索引具有下列两个独特之处:

  1.1因为索引是唯一的, 所以O r a c l e知道只有一个条目具有设定值。如果查找到了所期望的条目,则立即终止查找。

  1.2一旦遇到一个大于设定值的条目,索引的顺序搜索可被终止;

  2 ORDER BY中用索引

  ORDER BY 子句只在两种严格的条件下使用索引.

  ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.

  ORDER BY中所有的列必须定义为非空.

  WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列.

  例如:

  表DEPT包含以下列:

DEPT_CODE PK

NOT NULL

DEPT_DESC NOT NULL

DEPT_TYPE NULL

  非唯一性的索引(DEPT_TYPE)

  低效: (索引不被使用)

SELECT DEPT_CODE

FROM DEPT

ORDER BY DEPT_TYPE

EXPLAIN PLAN:

SORT ORDER BY

TABLE ACCESS FULL

  高效: (使用索引)

SELECT DEPT_CODE

FROM DEPT

WHERE DEPT_TYPE > 0

EXPLAIN PLAN:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

  3 避免改变索引列的类型.

  当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换.

假设 EMPNO是一个数值类型的索引列.

SELECT …

FROM EMP

WHERE EMPNO = ‘123'

  实际上,经过ORACLE类型转换, 语句转化为:

SELECT …

FROM EMP

WHERE EMPNO = TO_NUMBER(‘123')

  幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变.

  现在,假设EMP_TYPE是一个字符类型的索引列.

SELECT …

FROM EMP

WHERE EMP_TYPE = 123

  这个语句被ORACLE转换为:

SELECT …

FROM EMP

WHERE TO_NUMBER(EMP_TYPE)=123

  因为内部发生的类型转换, 这个索引将不会被用到! 为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来. 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型.

  4 需要当心的WHERE子句

  某些SELECT 语句中的WHERE子句不使用索引. 这里有一些例子.

  在下面的例子里, ‘!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中.

  不使用索引:

SELECT ACCOUNT_NAME

FROM TRANSACTION

WHERE AMOUNT !=0;

  使用索引:

SELECT ACCOUNT_NAME

FROM TRANSACTION

WHERE AMOUNT >0;

  下面的例子中, ‘||'是字符连接函数. 就象其他函数那样, 停用了索引. 不使用索引:

SELECT ACCOUNT_NAME,AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME||ACCOUNT_TYPE='AMEXA';

  使用索引:

SELECT ACCOUNT_NAME,AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME = ‘AMEX'

AND ACCOUNT_TYPE=' A';

  下面的例子中, ‘+'是数学函数. 就象其他数学函数那样, 停用了索引.

  不使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE AMOUNT + 3000 >5000;

  使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE AMOUNT > 2000 ;

  下面的例子中,相同的索引列不能互相比较,这将会启用全表扫描.

  不使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME = NVL(:ACC_NAME,ACCOUNT_NAME);

  使用索引:

SELECT ACCOUNT_NAME, AMOUNT

FROM TRANSACTION

WHERE ACCOUNT_NAME LIKE NVL(:ACC_NAME,'%');

  如果一定要对使用函数的列启用索引, ORACLE新的功能: 基于函数的索引(Function-Based Index) 也许是一个较好的

  方案.

CREATE INDEX EMP_I ON EMP (UPPER(ename)); /*建立基于函数的索引*/

SELECT * FROM emp WHERE UPPER(ename) = ‘BLACKSNAIL'; /*将使用索引*/

  5 怎样监控无用的索引

  Oracle 9i以上,可以监控索引的使用情况,如果一段时间内没有使用的索引,一般就是无用的索引

  语法为:

  开始监控:alter index index_name monitoring usage;

  检查使用状态:select * from v$object_usage;

  停止监控:alter index index_name nomonitoring usage;

  当然,如果想监控整个用户下的索引,可以采用如下的脚本:

set heading off

set echo off

set feedback off

set pages 10000

spool start_index_monitor.sql

SELECT 'alter index '||owner||'.'||index_name||' monitoring usage;'

FROM dba_indexes

WHERE owner = USER;

spool off

set heading on

set echo on

set feedback on

------------------------------------------------

set heading off

set echo off

set feedback off

set pages 10000

spool stop_index_monitor.sql

SELECT 'alter index '||owner||'.'||index_name||' nomonitoring usage;'

FROM dba_indexes

WHERE owner = USER;

spool off

set heading on

set echo on

set feedback on

一.索引介绍 

1.1 索引的创建语法: 

CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> 

      ON <schema>.<table_name> 

           (<column_name> | <expression> ASC | DESC, 

            <column_name> | <expression> ASC | DESC,...) 

     TABLESPACE <tablespace_name> 

     STORAGE <storage_settings> 

     LOGGING | NOLOGGING 

    COMPUTE STATISTICS 

     NOCOMPRESS | COMPRESS<nn> 

     NOSORT | REVERSE 

     PARTITION | GLOBAL PARTITION<partition_setting> 

相关说明 

1) UNIQUE | BITMAP:指定UNIQUE为唯一值索引,BITMAP为位图索引,省略为B-Tree索引。 

2)<column_name> | <expression> ASC | DESC:可以对多列进行联合索引,当为expression时即“基于函数的索引” 

3)TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高) 

4)STORAGE:可进一步设置表空间的存储参数 

5)LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用NOLOGGING来减少占用空间并提高效率) 

6)COMPUTE STATISTICS:创建新索引时收集统计信息 

7)NOCOMPRESS | COMPRESS<nn>:是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值) 

8)NOSORT | REVERSE:NOSORT表示与表中相同的顺序创建索引,REVERSE表示相反顺序存储索引值 

9)PARTITION | NOPARTITION:可以在分区表和未分区表上对创建的索引进行分区 

1.2 索引特点: 

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 

第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 

第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 

第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 

第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 

1.3 索引不足: 

第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 

第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 

第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 

1.4 应该建索引列的特点: 

1)在经常需要搜索的列上,可以加快搜索的速度; 

2)在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 

3)在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度; 

4)在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 

5)在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 

6)在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论