1、不要用"*"代替所有列名
使用*代替某個表的所有列名,這種寫法對Oracle系統來說存在解析的動態問題,Oracle通過查詢數據字典來將"*"轉換成所有列名,會消耗系統時間
2、用truncate代替delete
用delete刪除表中的數據行時,Oracle會使用撤銷表空間(UNDO Tablespace)來存放恢複的信息,如果用戶沒有發出commit命令而是rollback命令,Oracle會將數據恢複到刪除之前的狀態。用truncate刪除表數據行時是不會寫入回滾段或者撤銷表空間的,速度會快很多,如果希望刪除全表數據,建議使用truncate。【慎用truncate,慎用truncate,慎用truncate】
使用方法是truncate table tb_name
3、在確保數據完整性的情況下多用commit
commit可以實現dml語句的及時提交,同時也釋放事務所占用的資源
commit所釋放的資源有:
回滾段上用于恢複數據的信息,撤銷表空間也只進行短暫的保留
被程序語句獲得的鎖
Redo log buffer中的空間
Oracle爲管理上述資源的內部開銷
4、盡量減少表的查詢次數
5、用not exists替代not in,用exists替代in
在子查詢中,not in子句將執行一個內部的排序和合並,它對子查詢中的表執行了一個全表遍曆,這種情況下效率最低。
select empno, ename, job, mgr, hiredate, sal, comm, deptno
from emp t1 where not exists (select 1 from dept t2 where t2.deptno = t1.deptno and t2.deptno = 10);
select empno, ename, job, mgr, hiredate, sal, comm, deptno
from emp t1 where t1.deptno not in (select deptno from dept t2 where t2.deptno = 10);
select empno, ename, job, mgr, hiredate, sal, comm, deptno
from emp t1 where exists (select 1 from dept t2 where t2.deptno = t1.deptno and t2.deptno = 10);
select empno, ename, job, mgr, hiredate, sal, comm, deptno
from emp t1 where t1.deptno in (select deptno from dept t2 where t2.deptno = 10);
注意:
- 請用數據量較大的表測試
- 數據量很少時可以用not in
- in的參數最大不能超過1000個
6、用exists替代distinct
--查詢所有雇員的部門號碼、部門名稱,下面兩個SQL實現了同樣的效果
select t.deptno, t.dname from dept t where exists (select 1 from emp b where b.deptno = t.deptno);
select distinct t.deptno, t.dname from dept t, emp b where b.deptno = t.deptno;