日期:2014-05-16  浏览次数:20409 次

oracle语句优化原则

1.select t1.* from table1 t1,table2 t2
oracle的解析器是由右向左的,所以应该以数量较少的表做基础表,放在右面
注:如果是三张表,将其中的引用表作为基础表
select t1.* from table1 t1,table t2,table t3 where t1.id=t3.id and t2.name=t3.name
2.select * from? emp where id>5000 and name like '张%' and 25<(select count(*) from emp)
oracle采用自下而上的顺序解析where子句,所以表之间的链接必须写在where条件之前,那些可以过滤掉很多数据的条件放在where的末尾
3.select子句中避免使用"*"
数据库会从字典表将*转化成为各个列,需要消耗很长时间
4.减少数据库的访问次数(设置变量)
select t1.name,t2.name from table1 t1,table2 t2 where t1.id=1 and t2.id=2
5.删除重复的语句(更高效)
delete form emp e where e.rowid>(select min(x.rowid) from emp x where x.emp_no=e.emp_no);
6.用truncate代替delete
不基于事务,所以快,但是删除后无法恢复
7.尽可能多的使用commit
8.速度:select count(t.id) from emp > select count(*) from emp >select count(1) from emp
9.避免使用having,HAVING 只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作
低效:select t.name from emp t group by t.name having t.name !='张三'
高效:select t.name from emp t where t.name!='张三'? group by t.name
10.减少对表的查询
?低效:select tab_name
?from tables?
?where? tab_name = ( select tab_name? from tab_columns? where? version =? 604 )
?and? db_ver = ( select db_ver? from tab_columns? where? version =? 604 );
?高效:select tab_name
?from tables?
?where? (tab_name, db_ver) = ( select tab_name, db_ver) from tab_columns
?where? version =? 604 );
11.用exist代替in ; 用in代替or (代替distinct?)
效率:表连接>exist>in>or
12.使用索引
(1)优点:提高效率、确保主键的唯一性
(2)缺点:需要空间,每当有记录在表中增减或索引列被修改时,索引本身也会被修改。这意味着每条记录的INSERT,DELETE,UPDATE 将为此多付出4,5 次的磁盘I/O。
??? 那些不必要的索引反而会使查询反应时间变慢。------##定期的重构索引是有必要的##
? 注意:
?(1)(等式索引和范围索引)
?select lodging from lodging where? lodging like 'm%';由于索引范围查询将返回一组值,它的效率就要比索引唯一扫描低一些
?select lodging from lodging where? manager like '%hanman';如果索引列所对应的值的第一个字符由通配符(WILDCARD) 开始,索引将不被采用
?(2)
?唯一性索引的等级高于非唯一性索引。然而这个规则只有当WHERE 子句中索引列和常量比较才有效,
?如果不同表中两个相同等级的索引将被引用,FROM 子句中最后的表的索引将有最高的优先级

13.避免在索引处使用计算
低效:select * from dept where sal * 12 > 25000;
高效:select * from dept where sal > 25000/12;
14.用>=替代>
15.避免使用is null 和 is not null
oracle会将not转化为:
?NOT >?? 自动转化为? <=
?NOT >=? 自动转化为? <
?NOT <?? 自动转化为? >=
?NOT <=? 自动转化为? >
16.
用UNION 替换WHERE 子句中的OR将会起到较好的效果。对索引列使用OR将造成全表扫描。注意,以上规则只针对多个索引列有效。如果有column 没有被索引,
查询效率可能会因为你没有选择OR而降低。
高效:
?select loc_id, loc_desc, region
?from location?
?where? loc_id = 10
?union?
?select loc_id, loc_desc, region?
?from location??
?where? region = 'MELBOURNE';
如果你坚持要用OR,那就需要返回记录最少的索引列写在最前面。
注意:
WHERE KEY1 = 10? /*返回最少记录*/?
OR KEY2 = 20??? /*返回最多记录*/
17.用WHERE替代ORDER BY,order by 不会使用非唯一性索引
WHERE 子句使用的索引和ORDER BY 子句中所使用的索引不能并列
18.避免改变索引列的类型
19.索引只能告诉你什么存在于表中,而不能告诉你什么不存在于表中,所以不要使用!=??? ||?? + 等等
20.避免使用耗费资源的操作,如DISTINCT ,UNION ,MINUS ,INTERSECT,ORDER BY,启动SQL
引擎执行耗费资源的排序(SORT)功能。DISTINCT 需要一次排序操作,而其他的至少需要执行两次排序。

?