1.多表查询
选择合适的基础表
select * from table1,table2,baseTable
- baseTable:相对记录数小
- baseTable table1,table2有共同关联的条件
选择最有效率的表名顺序
-
ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving
table)将被最先处理。 -
只在基于规则的优化器中有效
2. Where子句中的连接顺序
Oracle采用自下而上的顺序解析WHERE子句。
先写表关联后写条件:过滤掉最大数量记录的条件必须写在WHERE子句的末尾
3.计算记录条数
select count(index_column) from Table;
或者
Select count(1) from tablename;
4.使用EXSITS替代IN
select * from TRANS a WHERE EXISTS
(SELECT b.ACCOUNT from CUST b WHERE b.ACCOUNT = a.ACCOUNT )
5.使用表连接替代EXSITS
6.索引的注意点
(1) 范围与等式的优先级
SELECT ENAME FROM EMP
WHERE DEPTNO > 20 //不管有没有索引
AND EMP_CAT = ‘A’; //优先
(2) 运算
SELECT ENAME
FROM EMP
WHERE EMPNO = 7935
AND DEPTNO + 0 = 10 /*DEPTNO上的索引将失效*/
AND EMP_TYPE || ‘’ = ‘A’ /*EMP_TYPE上的索引将失效*/
(3)优先使用唯一性索引
(4)避免在索引列上使用NOT
(5)用 >= 替代 >
(6)避免在索引列上使用is null和is not null
SELECT …
FROM DEPARTMENT
WHERE DEPT_CODE >=0;//推荐
(7)总是使用索引的第一个列
(8)使用UNION ALL替代UNION
(9)避免隐式改变索引列的类型
/*假设EMP_TYPE是一个字符类型的索引列.*/
SELECT …
FROM EMP
WHERE EMP_TYPE = 123
(10)小符号
不使用索引: | 使用索引: |
---|---|
!=0; | > 0; |
与 | and |
+ | > |
ACCOUNT_NAME = NVL(:ACC_NAME, ACCOUNT_NAME) | ACCOUNT_NAME LIKE NVL(:ACC_NAME, ’%’) |
(11) 避免使用耗费资源的操作
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎 DISTINCT需要一次排序操作,而其他的至少需要执行两次排序。
(12)GROUP BY写法
先写条件后分组
(13)使用日期
当使用日期时,需要注意如果有超过5位小数加到日期上,这个日期会进到下一天!
SELECT TO_DATE(‘01-JAN-93’+.99999)
FROM DUAL
Returns:
’01-JAN-93 23:59:59’
SELECT TO_DATE(‘01-JAN-93’+.999999)
FROM DUAL
Returns:
’02-JAN-93 00:00:00’