ORACLE SQL性能优化系列 (十)
2024-08-29 13:30:39
供稿:网友
本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。
31. 强制索引失效
如果两个或以上索引具有相同的等级,你可以强制命令oracle优化器使用其中的一个(通过它,检索出的记录数量少) .
举例:
select ename
from emp
where empno = 7935
and deptno + 0 = 10 /*deptno上的索引将失效*/
and emp_type || ‘’ = ‘a’ /*emp_type上的索引将失效*/
这是一种相当直接的提高查询效率的办法. 但是你必须谨慎考虑这种策略,一般来说,只有在你希望单独优化几个sql时才能采用它.
这里有一个例子关于何时采用这种策略,
假设在emp表的emp_type列上有一个非唯一性的索引而emp_class上没有索引.
select ename
from emp
where emp_type = ‘a’
and emp_class = ‘x’;
优化器会注意到emp_type上的索引并使用它. 这是目前唯一的选择. 如果,一段时间以后, 另一个非唯一性建立在emp_class上,优化器必须对两个索引进行选择,在通常情况下,优化器将使用两个索引并在他们的结果集合上执行排序及合并. 然而,如果其中一个索引(emp_type)接近于唯一性而另一个索引(emp_class)上有几千个重复的值. 排序及合并就会成为一种不必要的负担. 在这种情况下,你希望使优化器屏蔽掉emp_class索引.
用下面的方案就可以解决问题.
select ename
from emp
where emp_type = ‘a’
and emp_class||’’ = ‘x’;
32. 避免在索引列上使用计算.
where子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描.
举例:
低效:
select …
from dept
where sal * 12 > 25000;
高效:
select …
from dept
where sal > 25000/12;
译者按:
这是一个非常实用的规则,请务必牢记
33. 自动选择索引
如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性.
在这种情况下,oracle将使用唯一性索引而完全忽略非唯一性索引.
举例:
select ename
from emp
where empno = 2326
and deptno = 20 ;
这里,只有empno上的索引是唯一性的,所以empno索引将用来检索记录.
table access by rowid on emp
index unique scan on emp_no_idx
34. 避免在索引列上使用not
通常, 我们要避免在索引列上使用not, not会产生在和在索引列上使用函数相同的
影响. 当oracle”遇到”not,他就会停止使用索引转而执行全表扫描.
举例:
低效: (这里,不使用索引)
select …
from dept
where dept_code not = 0;
高效: (这里,使用了索引)
select …
from dept
where dept_code > 0;
需要注意的是,在某些时候, oracle优化器会自动将not转化成相对应的关系操作符.
not > to <=
not >= to <
not < to >=
not <= to >
译者按:
在这个例子中,作者犯了一些错误. 例子中的低效率sql是不能被执行的.
我做了一些测试:
sql> select * from emp where not empno > 1;
no rows selected
execution plan
----------------------------------------------------------
0 select statement optimizer=choose
1 0 table access (by index rowid) of 'emp'
2 1 index (range scan) of 'empno' (unique)
sql> select * from emp where empno <= 1;
no rows selected
execution plan
----------------------------------------------------------
0 select statement optimizer=choose
1 0 table access (by index rowid) of 'emp'
2 1 index (range scan) of 'empno' (unique)
两者的效率完全一样,也许这符合作者关于” 在某些时候, oracle优化器会自动将not转化成相对应的关系操作符” 的观点.
35. 用>=替代>
如果deptno上有一个索引,
高效:
select *
from emp
where deptno >=4
低效:
select *
from emp
where deptno >3
两者的区别在于, 前者dbms将直接跳到第一个dept等于4的记录而后者将首先定位到deptno=3的记录并且向前扫描到第一个dept大于3的记录.