索引是由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将维护单个表列的索引(建立在单一表列上)或复合索引(建立在多个表列上)。复合索引称并置索引。

一、主关键字的约束

  关系数据库理论指出,在表中能唯一标识表的每个数据行的一个或多个表列是对象的主关键字。由于数据字典中定义的主关键字能确保表中数据行之间的唯一性,因此,在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一旦遇到一个大于设定值的条目,索引的顺序搜索可被终止;

二、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

三、避免改变索引列的类型

  当比较不同数据类型的数据时, 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会优先转换数值类型到字符类型.

四、需要当心的where子句

某些select 语句中的where子句不使用索引. 这里有一些例子:

1、IS NULL 与 IS NOT NULL 
  不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。 
  任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。

2、'!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中

不使用索引: select * from employee where salary<>3000; 
使用索引: select account_name from transaction where amount >0; 
使用索引: select * from employee where salary<3000 or salary>3000;

3、联接列,'||'是字符连接函数. 就象其他函数那样, 停用了索引

不使用索引: 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';

4、'+'是数学函数. 就象其他数学函数那样, 停用了索引

不使用索引: select account_name, amount from transaction where amount + 3000 >5000; 
使用索引: select account_name, amount from transaction where amount > 2000 ;

5、相同的索引列不能互相比较,这将会启用全表扫描

不使用索引: 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,'%');

6、带通配符(%)的like语句

不使用索引: select * from employee where last_name like '%cliton%'; 
使用索引: select * from employee where last_name like 'c%'

7、IN和EXISTS

不使用索引: ... where column in(select * from ... where ...); 
使用索引: ... where exists (select 'X' from ...where ...); 
同时应尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高。

如果一定要对使用函数的列启用索引: 
1、oracle新的功能: 基于函数的索引(function-based index) 也许是一个较好的方案: 
create index emp_i on emp (upper(ename)); /*建立基于函数的索引*/ 
select * from emp where upper(ename) = 'BLACKSNAIL'; /*将使用索引*/ 
2、MS SQL Server显示申明指定索引: 
SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN ('男','女')

五、怎样监控无用的索引

  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

原文:http://czllfy.iteye.com/blog/510282

Oracle中索引的使用 索引性能优化调整的更多相关文章

  1. Atitit 如何利用先有索引项进行查询性能优化

    Atitit 如何利用先有索引项进行查询性能优化 1.1. 再分析的话就是我们所写的查询条件,其实大部分情况也无非以下几种:1 1.2. 范围查找 动态索引查找1 1.2.1. 索引联合 所谓的索引联 ...

  2. Oracle中NULL值与索引

    NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于 ...

  3. MySQL索引使用方法和性能优化

    在自己的一个项目中,数据比较多,搜索也很频繁,这里找到一个建立索引很不错的文章,推荐下. 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的 ...

  4. 【转】Oracle Freelist和HWM原理及性能优化

    文章转自:http://www.wzsky.net/html/Program/DataBase/74799.html 近期来,FreeList的重要作用逐渐为Oracle DBA所认识,网上也出现一些 ...

  5. Oracle多表连接效率,性能优化

    Oracle多表连接,提高效率,性能优化 (转) 执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只 ...

  6. oracle中如何生成awr【性能调优】报告

    1.进入数据库 sqlplus / as sysdba 2.查看用户 show parameter db_name 3.开始压测后执行 exec DBMS_WORKLOAD_REPOSITORY.CR ...

  7. 怎么解决ORACLE 中 CHAR类型的索引问题

    在很多场景中,都有如下情况 trim(a.colunm1) = trim(b.colunm2) 应该怎么优化呢? 用到 TRIM 的很多原因是某些系统为了提高查询效率,不使用  ORACLE 的特有的 ...

  8. oracle中查询用户表/索引/视图创建语句

    不多说,直接上干货 1.查询当前用户下表的创建语句 select dbms_metadata.get_ddl('TABLE','ux_future') from dual; 2.查询其他用户下表的创建 ...

  9. oracle中提高order by的性能

    1.如果order by columnA,那么在where查询条件中添加条件columnA=value,则oracle内部会过滤order by排序,直接用索引(可以通过execution plan查 ...

随机推荐

  1. C11多线程

    参考: http://www.oschina.net/translate/cplusplus-11-threading-make-your-multitasking-life http://blog. ...

  2. Abstract Factory 抽象工厂

    意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 一个系统要独立于它的产品的创建.组合和表示时 结构 参与者 AbstractFactory:声明一个创建抽象产品对象 ...

  3. C#中 EF(EntityFramework) 性能优化

    现在工作中很少使用原生的sql了,大多数的时候都在使用EF.刚开始的时候,只是在注重功能的实现,最近一段时间在做服务端接口开发.开发的时候也是像之前一样,键盘噼里啪啦的一顿敲,接口秒秒钟上线,但是到联 ...

  4. 使用Merge存储引擎实现MySQL分表

    一.使用场景 Merge表有点类似于视图.使用Merge存储引擎实现MySQL分表,这种方法比较适合那些没有事先考虑分表,随着数据的增多,已经出现了数据查询慢的情况. 这个时候如果要把已有的大数据量表 ...

  5. eclipse中运行 main 方法报错,找不到类

    eclipse (maven 项目)中运行 main 方法报错,找不到类 ** 发现:在 eclipse中的 "Marker" 控制面板中 ,发现问题所在 只要删除 maven 仓 ...

  6. MXNet——symbol

    参考资料:有基础(Pytorch/TensorFlow基础)mxnet+gluon快速入门 symbol symbol 是一个重要的概念,可以理解为符号,就像我们平时使用的代数符号 x,y,z 一样. ...

  7. CSUOJ 1018 Avatar

    Description In the planet Pandora, Jake found an old encryption algorithm. The plaintext, key and ci ...

  8. 绝对良心的 Java 中发邮件功能

    开篇语,是不是感觉这个功能都老掉牙了,网上一大推的文章,随便找个代码就是了,为什么我还要选择专门写一篇呢,因为我遇到了不一样的坑…… 首先,不免俗套的把代码都贴上来,拿去执行吧,记住换上你的账号和授权 ...

  9. bzoj——2127: happiness

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2570  Solved: 1242[Submit][Status][D ...

  10. 你的跑步姿势正确吗? 教你正确跑步姿势 & 常识

    转载!!!!!搞IT必须运动一下 前言: 最近两年跑步的人越来越多,跑步在大部分人的观念中都是毫无技术含量,只要迈开腿就行了,其实这也是造成大多数跑步人士伤病的根源.对跑步的认知不足,跑步是一项看起来 ...