常规SQL语句优化
1.建议不用“*”来代替所有列名,建议用户在写select语句时,采用与访问表有关的实例列名。
2.用TRUNCATE 代替DELETE,delete删除表的数据行时,需要把删除的数据会在撤销表空间里面存放,当用户没有发出commit命令,而发出rollback时,系统会恢复删除之前的状态。当用户使用TRUNCATE对表数据删除时,不会把删除的数据写入到回滚段,速度要快一些。所以当对表或者簇中的所有行全部删除时,采用truncate更加有效。
3.在确保完整性的情况下多用commit语句,提交命令后,事物处理完毕,释放资源,建议在每个块的end前面使用commit语句。
commit所释放的资源如下:
1)回滚段上用户恢复数据的信息,撤销表空间也只做短暂的保留。
2)被程序语句获得的锁
3)redo log buffer中的空间
4)oracle为管理上述资源的内部花费。
4.尽量减少表的查询次数
对于含有子查询的SQL语句中,
select empno,ename,job from emp?
where deptno in (select deptno from dept where loc=‘BEIJING')
or deptno in (select depton from dept where loc='NEW YORK');
修改成
select empno,ename,job from emp?
where deptno in (select deptno from dept where loc=‘BEIJING' or loc=‘NEW YORK')
分析:第一sql子查询需要查询两次,第二sql值查询一次,在大量数据查询时,第二种要更快一些。
5.用【not】exists 代替 【not】in?
因为in是遍历全表,所以是低效的。in后面结果集如果是列表或者结果集很少时候可以使用的
案例:
select EMPNO,ENAME,"JOB" from SCOTT.emp
where EMPNO not in (select deptno from scott.dept where loc='bj');
改成
select EMPNO,ENAME,"JOB" from SCOTT.emp
where EXISTS(select deptno from SCOTT.dept where loc!='bj');
显示的结果集都是相同的,但是这个改写没太看明白什么意思,感觉有点类似取条件的反义来获得结果集。
第一sql条件:雇员编号不在北京工作的部门编号查询结果中的记录显示出来,两个表比对的字段不一致,这样比对个人感觉不到有什么意义。
第二sql条件:北京地点除外的部门编号结果集
总之两个where的条件就是 ,查询工作地点不在北京部门编号结果集。
--------查阅用法------------------------------------
exists表示()内子查询语句返回结果不为空说明where条件成立就会执行主sql语句, 如果为空就表示where条件不成立,sql语句就不会执行。 not exists和exists相反,子查询语句结果为空, 则表示where条件成立,执行sql语句。负责不执行
最终下面的语句改写成
select EMPNO,ENAME,"JOB" from SCOTT.emp
where EXISTS(select deptno from SCOTT.dept where loc!='bj' and DEPTNO=SCOTT.EMP.DEPTNO);
查询结果集一致,先这样吧,以后实践时候在仔细研究案例吧