Oracle中索引的使用 索引性能优化调整
索引是由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中索引的使用 索引性能优化调整的更多相关文章
- Atitit 如何利用先有索引项进行查询性能优化
Atitit 如何利用先有索引项进行查询性能优化 1.1. 再分析的话就是我们所写的查询条件,其实大部分情况也无非以下几种:1 1.2. 范围查找 动态索引查找1 1.2.1. 索引联合 所谓的索引联 ...
- Oracle中NULL值与索引
NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于 ...
- MySQL索引使用方法和性能优化
在自己的一个项目中,数据比较多,搜索也很频繁,这里找到一个建立索引很不错的文章,推荐下. 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的 ...
- 【转】Oracle Freelist和HWM原理及性能优化
文章转自:http://www.wzsky.net/html/Program/DataBase/74799.html 近期来,FreeList的重要作用逐渐为Oracle DBA所认识,网上也出现一些 ...
- Oracle多表连接效率,性能优化
Oracle多表连接,提高效率,性能优化 (转) 执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只 ...
- oracle中如何生成awr【性能调优】报告
1.进入数据库 sqlplus / as sysdba 2.查看用户 show parameter db_name 3.开始压测后执行 exec DBMS_WORKLOAD_REPOSITORY.CR ...
- 怎么解决ORACLE 中 CHAR类型的索引问题
在很多场景中,都有如下情况 trim(a.colunm1) = trim(b.colunm2) 应该怎么优化呢? 用到 TRIM 的很多原因是某些系统为了提高查询效率,不使用 ORACLE 的特有的 ...
- oracle中查询用户表/索引/视图创建语句
不多说,直接上干货 1.查询当前用户下表的创建语句 select dbms_metadata.get_ddl('TABLE','ux_future') from dual; 2.查询其他用户下表的创建 ...
- oracle中提高order by的性能
1.如果order by columnA,那么在where查询条件中添加条件columnA=value,则oracle内部会过滤order by排序,直接用索引(可以通过execution plan查 ...
随机推荐
- 2款适合HTML做音频和视频的插件
Flowplayer-视频播放器 Flowplayer 是一个开源(GPL 3的)WEB视频播放器.您可以将该播放器嵌入您的网页中,如果您是开发人员,您还可以自由定制和配置播放器相关参数以达到您要的播 ...
- hdoj1050 Moving Tables(贪心)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1050 题意 有一条走廊,走廊两边各有200个房间,一边的房间编号是奇数,另一边是偶数.现在有n个箱子需 ...
- mysql关于数据库表的水平拆分和垂直拆分
最初知道水平垂直分表的时候是刚参加工作不久的时候,知道了这个概念,但是公司用户量和数据量始终没上来,所以也没用到过,知道有一天到了一家新公司后,这些才被应用到实际开发中,这里我就大概说说关于水平和垂直 ...
- 加密grub防止通过单用户模式破解root密码
(1).CentOS6 1)产生加密密码 [root@CentOS6 ~]# grub-md5-crypt Password: Retype password: $1$QPduF0$FNhzDUPQP ...
- NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入
上一节我们讲到实体,仓储接口和仓储接口的实现需要遵循约定的命名规范,不仅是规范,而且为了依赖注入,现在我们实现仓储的依赖注入 在NetCore WebApi项目中新添加一个文件夹(Unit),当然你也 ...
- [ 转载 ] js十大排序算法:冒泡排序
js十大排序算法:冒泡排序 http://www.cnblogs.com/beli/p/6297741.html
- 如何破解安卓App
韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 如何破解安卓App
- luoguP4571 [JSOI2009]瓶子和燃料 裴蜀定理
裴蜀定理的扩展 最后返回的一定是\(k\)个数的\(gcd\) 因此对于每个数暴力分解因子统计即可 #include <map> #include <cstdio> #incl ...
- 【20181031T1】一串数字【分解质因数+贪心】
题面 [错解] 立方就是所有质因子次数都是3的倍数嘛 发现1e5的三次根很小,可以枚举所有和这个数乘起来是完全立方数的(flag*1) 然后--连条边跑最大独立集? 不对啊是NP问题(实际上是个二分图 ...
- Go Web编程 第三章--接收请求
net/http标准库 net/http标准库通常包括两个部分,客户端和服务器,我们可以通过ListenAndServe创建一个简陋的服务器 package main import ( "n ...