分析:注意所使用的时间的不同只要简单地改变所给出的统计的次序,第二个查询比第一个查询快了14 秒,那么可以设想一下当查询的结构设计不好的时候耗用几个小时的情形。
注:在SQL*Plus中可设置TIMING为ON(缺省为OFF),这样对于每条SQl语句,将会返回Oracle执行该语句所用的时间。
2.7 更新大量的数据
当更新大量的数据的时候可能会出现数据库性能的变差,特别是在业务高峰期间,我们建议在非业务期间进行,对于特别大量的更新,建议使用性能上的调优技术(这里可能包括删除索引,直接插入等调整技术),或者由我们DBA来规划进行。这里所说的更新包括:插入,更新,删除。
[@more@]2.8 经常性的COMMIT
COMMIT可以将事务中所作的任何改变写到实际的表中,但是在后台它做的工作不只如此,数据库中,有一个区域是用以存储全部的写到实际表中之前的事务数据的,ORACLE将这一区域叫做ROLLBACK段,当你执行一个COMMIT命令以后,与你的SQL相关联的事务会将ROLLBACK段中的内容写到实际的表中,然后更新这一区域,ROLLBAKC段中的原有内容就被删除了,ROLLBACK命令是另一种清除ROLLBACK段的命令方法,只是它不将所做的改动写到目标表中。
COMMIT所释放的资源:
l 回滚段上用于恢复数据的信息
l 被程序语句获得的锁
l redo log buffer 中的空间
l ORACLE为管理上述3种资源中的内部花费
如你所料,如果你一直不执行COMMIT或ROLLBACK命令,那么事务就会一直保存在ROLLBACK段中,随之而来的是如果你要装入的数据大小比ROLLBACK段的可用空间还要大,数据库将会终止并挂起所有的活动事务,不运行COMMIT命令是通用程序的一个缺陷,有规律地使用COMMIT命令将会使数据库系统输入的性能稳定。
经常我们会收到快照太旧和资源被占用等等的错误,这都是没有经常性的COMMIT造成的,所以建议大家在完成一定数量的更新后能够及时COMMIT。
2.9 存储过程
如果所使用的查询有规律可循,那么你可以试着使用过程,过程可以调用很大的一组SQL 的语句,过程是被数据库的引擎编译后运行的,与SQL语句不同,数据库引擎在执行过程的时候不需要进行优化,过程相对于独立的多个SQL语句它对于用户来说更容易使用,而对于数据库来说更为有效。
2.10 避免使用OR
如果可能的话,应该在查询尽量避免使用逻辑操作符OR,OR会不可避免的根据表的大小降低查询的速度。我们发现IN通常比OR要快。虽然优化器的文档中并不是这样说的。
2.11 SELECT子句中避免使用‘*’
当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*’是一个方便的方法。不幸的是,这是一个非常低效的方法。实际上,ORACLE在解析的过程中,会将‘*’依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。
2.12 减少访问数据库的次数
当执行每条SQL语句时,ORACLE在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量, 读数据块等等。由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量。
例如,
以下有三种方法可以检索出雇员号等于0342和0291的职员。
方法1 (最低效)
SELECT EMP_NAME , SALARY , GRADE
FROM EMP
WHERE EMP_NO = 342;
SELECT EMP_NAME , SALARY , GRADE
FROM EMP
WHERE EMP_NO = 291;
方法2 (次低效)
DECLARE
CURSOR C1 (E_NO NUMBER) IS
SELECT EMP_NAME,SALARY,GRADE
FROM EMP
WHERE EMP_NO = E_NO;
BEGIN
OPEN C1(342);
FETCH C1 INTO …,..,.. ;
OPEN C1(291);
FETCH C1 INTO …,..,.. ;
CLOSE C1;
END;
方法3 (高效)
SELECT A.EMP_NAME , A.SALARY , A.GRADE,
B.EMP_NAME , B.SALARY , B.GRADE
FROM EMP A, EMP B
WHERE A.EMP_NO = 342
AND B.EMP_NO = 291;
2.13 避免在索引列上使用计算.
WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描。
举例:
低效:
SELECT …
FROM DEPT
WHERE SAL * 12 > 25000;
高效:
SELECT …
FROM DEPT
WHERE SAL > 25000/12;
2.14 避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。对于单列索引,如果列包含空值,索引中将不存在此记录。 对于复合索引,如果每个列都为空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中。