实际开发中的OracleSQL优化建议
1)避免select *
2)编写sql尽量使用相同的编码风格。语句解析、语句执行、返回执行结果等几个步骤。共享的sga区,如有省去解析sql
3)使用truncate替换delete。delete属于dml语言。
4)在确保业务逻辑前提下及时commit事务
5)in:子查询->主查询 exists:主查询->子查询。子查询的记录较少,主查询是记录较大且有索引使用in,反之亦然。
not exists 的效率什么时候都高于not in
6)使用exists替代distinct
低效sql:
select distinct e.deptno,d.dname from dept d ,emp e where d.deptno = e.deptno
高效sql:
select d.deptno,d.dname from dept d where exists(select * from emp e where e.deptno = d.deptno)
7)使用union替换union all
union->去重,排序;union all->简单的结果连接
8)在保证功能的前提下减少对表的查询
低效sql:
select ename,job,sal,deptno from emp where job = (select job from emp where ename = 'scott')
and deptno = (select deptno from emp where ename = 'scott');
高效sql:
select ename,job,sal,deptno from emp where (job,deptno) = (select job,deptno from emp where ename = 'scott');
9)尽量使用表的别名(alias),并在列前标注来自哪个表
低效sql:
select ename,job,sal,emp.deptno from emp,dept where emp.deptno = dept.deptno;
高效sql:
select e.ename,e.job,e.sal,e.deptno from emp e,dept d where e.deptno = d.deptno;
10)不要使用having子句实现where子句的功能
带分组的sql,尽可能地把筛选条件放到where子句中进行筛选,having用来对分组过的结果进行过滤
11)在表连接中的优化原则
*识别驱动表,将数据量最小的表作为驱动表
*如果是多个连接条件查询,将过滤掉最多纪录的条件放到最前面(也就是where后面有多个条件)
12)合理使用索引
*避免全表扫描:没有索引,没有where条件,查询条件的列没有索引,查询条件中对索引列使用了函数或算数表达式
ex: where upper(job) = 'saleman' ->使用函数
where not in('clark','saleman') ->条件中not in
where job is not null ->条件中有is null,is not null,<>,!=
where job like '%saleman%'
*尽量避免使用like操作符
*避免对大表查询中的列使用单行函数或算数表达式
-> where trunc(birthday,'year') = '1998'
优化为:
where birthday >= '1998-01-01'
and birthday <= '1998-12-31'
-> where birthday + 30 = sysdate 避免在索引列上进行计算
优化为:;
where birthday = sysdate + 30;
-> where productid = 12345678; 进行隐式数据类型转换也会使索引失效
优化为:
where productid = '12345678'
*对于order by 语句中的列上如果没有索引会降低性能,建议在经常排序的列上添加索引,并且避免在这些列上使用函数表示式