SELECT . . . FROM emp WHERE dept_no NOTIN ( SELECT dept_no FROM dept WHERE dept_cat ='A');
改用以下:
1.5.用EXISTS代替DISTINCT
例如:查询所有员工所在的部门
SELECTDISTINCT dept_no, dept_name FROM dept D, emp E WHERE D.dept_no = E.dept_no ; Execution Plan --------------------------------------------------- SELECT STATEMENT OPTIMIZER HINT: CHOOSE SORT (UNIQUE) NESTED LOOPS TABLE ACCESS (FULL) OF'EMP' TABLE ACCESS (BY ROWID) OF'DEPT' INDEX (UNIQUE SCAN) OF'DEPT_PK' (UNIQUE) 优化后 SELECT dept_no, dept_name FROM dept D WHEREEXISTS ( SELECT'X' FROM emp E WHERE E.dept_no = D.dept_no ); Execution Plan --------------------------------------------------- SELECT STATEMENT OPTIMIZER HINT: CHOOSE FILTER TABLE ACCESS (FULL) OF'DEPT' TABLE ACCESS (BY ROWID) OF'EMP' INDEX (RANGE SCAN) OF'EMP_DEPT_IDX'
1.6.用IN 或 UNION 代替OR
前提条件是各条件必须有索引时
例如:
loc_id 和 region 都是有索引的
原语句: SELECT . . . SELECT . . . FROM location FROM location WHERE loc_id =10WHERE loc_id =10 OR region ='MELBOURNE'OR loc_id =20 OR loc_id =30 优化后 SELECT . . . SELECT . . . FROM location FROM location WHERE loc_id =10WHERE loc_in IN (10,20,30) UNION SELECT . . . FROM location WHERE region ='MELBOURNE'
SELECT . . . FROM emp E WHEREEXISTS ( SELECT'X' FROM dept WHERE dept_no = E.dept_no AND dept_cat ='A' ) AND E.emp_type = `MANAGER' SELECT . . . FROM emp E WHERE E.emp_type = 'MANAGER' OR EXISTS ( SELECT 'X' FROM dept WHERE dept_no = E.dept_no AND dept_cat = 'A' )
1.15.用DECODE 减少处理
The DECODE statement provides a way to avoid having to scan the same rows repetitively, or to join the same table repetitively. Consider the following example:
SELECTCOUNT(*), SUM(salary) FROM emp WHERE dept_no =0020 AND emp_name LIKE'SMITH%' ; SELECTCOUNT(*), SUM(salary) FROM emp WHERE dept_no =0030 AND emp_name LIKE'SMITH%' ; You can achieve the same result much more efficiently with DECODE: SELECTCOUNT(DECODE(dept_no, 0020, 'X', NULL)) D0020_kount, COUNT(DECODE(dept_no, 0030, 'X', NULL)) D0030_kount, SUM (DECODE(dept_no, 0020, salary, NULL)) D0020_sal, SUM (DECODE(dept_no, 0030, salary, NULL)) D0030_sal FROM emp WHERE emp_name LIKE'SMITH%';