Oracle SQL调优除此之外还有以下几方面的注意点:
1. 选择最有效率的表名顺序
由于ORACLE解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理。
当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行排序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并。
EXP:
表 TAB1 16,384 条记录
表 TAB2 1 条记录
选择TAB2作为基础表 (最好的方法)
select count(*) from tab1,tab2 执行时间0.96秒
select count(*) from tab2,tab1 执行时间26.09秒
2. WHERE子句中的连接顺序
由于ORACLE解析器按照从右到左的顺序处理,所以那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。
EXP:
(低效,执行时间156.3秒)
SELECT … FROM EMP E
WHERE SAL >50000
AND JOB = ‘MANAGER’
AND 25 < (SELECT COUNT(*) FROM EMP);
WHERE MGR=E.EMPNO)
(高效,执行时间10.6秒)
SELECT … FROM EMP E
WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO)
AND SAL >50000
AND JOB = ‘MANAGER’
3. 减少访问数据库的次数
当执行每条SQL语句时, ORACLE在内部执行了许多工作:
解析SQL语句,估算索引的利用率,绑定变量, 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量。
4. 高效的删除重复记录
最高效的删除重复记录方法 ( 因为使用了ROWID)
EXP:
DELETE FROM EMP E
WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X
WHERE X.EMP_NO = E.EMP_NO);
5. 用TRUNCATE替代DELETE
Truncate–DDL
Delete—-DML
6. 尽量多使用COMMIT
COMMIT所释放的资源:
A、回滚段上用于恢复数据的信息.
B、被程序语句获得的锁
C、redo log buffer 中的空间
D、ORACLE为管理上述3种资源中的内部花费
NOTE: 在使用COMMIT时必须要注意到事务的完整性,现实中效率和事务完整性往往是鱼和熊掌不可得兼。
7. 用Where子句替换HAVING子句
避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序、总计等操作。
WHERE子句限制记录的数目,能减少这方面的开销。
8. 避免在索引列上使用NOT
使用NOT, 会停止使用索引转而执行全表扫描.
EXP:
低效: (这里,不使用索引)
SELECT … FROM DEPT WHERE NOT DEPT_CODE = 0;
高效: (这里,使用了索引)
SELECT … FROM DEPT WHERE DEPT_CODE > 0;
需要注意的是,在某些时候,ORACLE优化器会自动将NOT转化成相对应的关系操作符.
NOT > to <=
NOT >= to <
NOT < to >=
NOT <= to >
衍生出去的另一个调优及为用>=替代>。两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。
Jason之后会介绍如何利用ORACLE相关的工具进行调优,调优无止境,方法才是硬道理