SQL语句的优化规则
(1)去掉不必要的大表、全表扫描。不必要的大表、全表扫描会造成不必要的输入输出,而且还会拖垮整个数据库;
(2)检查优化索引的使用 这对于提高查询速度来说非常重要;
(3)检查子查询,考虑SQL子查询是否可以用简单连接的方式进行重新书写;
(4)调整PCTFREE和PCTUSED等存储参数优化插入、更新或者删除等操作;
(5)考虑数据库的优化器;
(6)考虑数据表的全表扫描和在多个CPU的情况下考虑并行查询。
1、索引的使用
(1)尽量使用索引
是全表扫描还是索引范围扫描主要考虑SQL的查询速度问题。试比较下面两条SQL语句:
①语句A:
SELECT dname,deptno FROM dept WHERE deptno NOT IN(SELECT deptno FROM emp);
②语句B:
SELECT dname,deptno FROM dept WHERE NOT EXISTS(SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
(2)索引不起作用的情况
①存在数据类型隐形转换
②列上有数学运算
③使用不等于(<>)运算
④使用substr字符串函数
⑤‘%’通配符在第一个字符
⑥字符串连接(||)
(3)函数的索引
例如,日期类型是经常用到的,而且在SQL语句中会使用to_char函数以查询具体的的范围日期。如:
select * from staff_member where TO_CHAR(birth_day,’YYYY’)=’2003’;
可以建立基于函数的索引如:
CREATE INDEX Ind_emp_birth ON staff_member (to_char((birth_day,’YYYY’));
2.SQL语句排序优化
排序发生的情况如下:
3.选择联合查询的联合次序
联合查询中如涉及到多个表的字段关联及查询,其SQL查询语句联合次序的不同写法,会导致语句对各表具体操作的步骤有不同的次序,所以虽然执行结果相同,但执行效率却不同4.SQL子查询的调整
(1)关联子查询和非关联子查询
非关联查询的开销——非关联查询时子查询只会执行一次,而且结果是排序好的,并保存在一个Oracle的临时段中,其中的每一个记录在返回时都会被父查询所引用。在子查询返回大量的记录的情况下,将这些结果集排序,以及将临时数据段进行排序会增加大量的系统开销。
关联查询的开销——对返回到父查询的记录来说,子查询会每行执行一次。因此,必须保证任何可能的时候子查询用到索引。
(2)在子查询中慎重使用IN或者NOT IN语句
在子查询中慎重使用IN或者NOT IN语句,使用where (NOT)exists的效果要好的多。
①带IN的关联子查询是多余的,因为IN子句和子查询中相关的操作的功能是一样的。
②为非关联子查询指定EXISTS子句是不适当的,因为这样会产生笛卡尔乘积。
③尽量不要使用NOT IN子句。
(3)慎重使用视图的联合查询
慎重使用视图的联合查询,尤其是比较复杂的视图之间的联合查询。一般对视图的查询最好都分解为对数据表的直接查询效果要好一些。
可以在参数文件中设置SHARED_POOL_RESERVED_SIZE参数,这个参数在SGA共享池中保留一个连续的内存空间,连续的内存空间有益于存放大的SQL程序包。