SQL优化——ORACLE
SQL优化——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
转载:itpub
SQL优化——ORACLE的更多相关文章
- SQL优化(Oracle)
		
(转)SQL优化原则 一.问题的提出 在应用系统开发初期.因为开发数据库数据比較少.对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,可是假设将应用系统提交实际应用后,随着数 ...
 - SQL优化 | Oracle 绑定变量
		
之前整理过一篇有关绑定变量的文章,不太详细,重新补充一下. Oracle 绑定变量 http://www.cndba.cn/Dave/article/1275 一.绑定变量 bind variable ...
 - ORACLE常用SQL优化hint语句
		
在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...
 - 基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)
		
基于Oracle的SQL优化(社区万众期待数据库优化扛鼎巨著) 崔华 编 ISBN 978-7-121-21758-6 2014年1月出版 定价:128.00元 856页 16开 编辑推荐 本土O ...
 - Oracle SQL 优化原则(实用篇)
		
由于SQL优化优化起来比较复杂,并且还受环境限制,在开发过程中,写SQL必须遵循以下几点原则: 1.Oracle 采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他Where ...
 - Oracle 建立索引及SQL优化
		
数据库索引: 索引有单列索引,复合索引之说,如果某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引.数据库索引主要进行提高访问速度. 建设原则: 1.索引应该经 ...
 - oracle sql优化
		
整理一下网上所看到sql优化方法 1.使用大写字母书写sql,因为oracle解释器会先将sql语句转换成大写后再解释 2 减少访问数据库的次数,多数情况下一条sql可以达到目的的,就不要使用多 ...
 - Oracle SQL优化一(常见方法)
		
1.表访问方式优化: a)普通表优先“Index Lookup 索引扫描”,避免全表扫描 大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表 ...
 - SQL性能优化(Oracle)
		
首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条记录, ...
 
随机推荐
- 吴裕雄--天生自然java开发常用类库学习笔记:IdentityHashMap类
			
import java.util.IdentityHashMap ; import java.util.HashMap ; import java.util.Set ; import java.uti ...
 - redis学习(五)
			
一.Redis 发布订阅 1.Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 2.Redis 客户端可以订阅任意数量的频道. 比如你订阅 ...
 - Golang的基础数据类型-字符型
			
Golang的基础数据类型-字符型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符型概述 Go语言中的字符有两种,即uint8类型和rune类型. uint8类型: 我们也 ...
 - UVA - 1572 Self-Assembly(图论模型+拓扑排序)
			
题意:判断利用给出的正方形是否能拼接出无限延伸的结构. 分析:正方形上的字母看做点,正方形看做有向边. 例如: 若上下两个正方形能拼接,需要B+~C+是个有向边. 对输入的处理是:把A+,A-分别映射 ...
 - POJ2392:Space Elevator
			
Space Elevator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9244 Accepted: 4388 De ...
 - 使用 Exchange 命令行管理程序查看动态通讯组的成员
			
本示例返回名为 "全职员工" 的动态通讯组的成员列表. 第一个命令将动态通讯组对象存储在变量$FTE中. 第二个命令使用 Get-Recipient cmdlet 列出与为动态通讯 ...
 - Easy_vb
			
拿到之后运行一下 之后使用ida打开先关键字搜索一下,结果就出来了
 - kafka创建topic,生产和消费指定topic消息
			
启动zookeeper和Kafka之后,进入kafka目录(安装/启动kafka参考前面一章:https://www.cnblogs.com/cici20166/p/9425613.html) 1.创 ...
 - mock的使用及取消,node模仿本地请求:为了解决前后端分离,用户后台没写完接口的情况下
			
借鉴:https://www.jianshu.com/p/dd23a6547114 1.说到这里还有一种是配置node模拟本地请求 (1)node模拟本地请求: 补充一下 [1]首先在根目录下建一个d ...
 - vue左侧菜单的实现
			
后端实现 django视图def menu(request): menu_list = models.Menu.objects.all().values('id', 'menu_name', 'par ...