//高效
SELECT * FROM EMP WHERE EMPNO > 0 AND EXISTS (SELECT DEPTNO FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'MELB'
//低效
SELECT * FROM EMP WHERE EMPNO > 0 AND DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB'
SELECT LOC_ID,LOG_DESC,REGION FROM LOCAITON WHERE LOC_ID =10 UNION SELECT LOC_ID,LOC_DESC,REGION FROM LOCATION WHERE REGION = 'MELBOURNE' //高效
SELECT LOC_ID,LOC_DESC,REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = 'MELBURNE' //低效
通常情况下,用UNION替换WHERE子句中的OR将会起到较好的效果
对索引列使用OR将造成全表扫描
以上规则只针对多个索引列有效,如果有column没有被索引,查询效率可能会因为你没有选择OR而降低
上面例子中,LOC_ID和REGION上面都建有索引
避免在索引列上使用IS NULL和IS NOT NULL
SELECT ... FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL //低效,索引失败
SELECT .. FROM DEPARTMENT WHERE DEPT_CODE > = 0 //高效,索引有效
ORDER BY子句只在两种两种严格的条件下使用索引//a.ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序//b.ORDER BY中所有的列必须定义为非空
WHERE子句使用的索引和ORDER BY子句中使用的索引不能并列
以表DEPT为例子
表DEPT包含以下列:
=============
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
=============
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE //低效,索引未使用
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0 //高效,索引已经使用
避免改变索引列的类型
当比较不同类型的数据时,ORACLE自动对列进行简单的类型转换,例如:EMPNO是一个数值类型的索引列:SELECT ... FROM EMP WHERE EMPNO = '123'。实际上,经过ORACLE类型转化为:SELECT ... FROM EMP WHERE EMPNO =TO_NUMBER('123')
低效: SELECT JOB , AVG(SAL) FROM EMP GROUP BY JOB HAVING JOB = ‘PRESIDENT' OR JOB = ‘MANAGER'
高效: SELECT JOB , AVG(SAL) FROM EMP WHERE JOB = ‘PRESIDENT' OR JOB = ‘MANAGER' GROUP BY JOB
提高GROUP BY 语句的效率,可以通过将不需要的记录在GROUP BY 之前过滤掉。下面两个查询返回相同结果但第二个明显就快了许多