选择一个好的表联接顺序(这是一个比较重要的原则)

当在WHERE子句中有多个表联接时,WHERE子句中排在最后的表应当是返回行数可能最少的表,有过滤条件的子句应放在WHERE子句中的最后。
如:设从emp表查到的数据比较少或该表的过滤条件比较确定,能大大缩小查询范围,则将最具有选择性部分放在WHERE子句中的最后:
select * from emp e,dept d where d.deptno >10 and e.deptno =30; 如果dept表返回的记录数较多的话,上面的查询语句会比下面的查询语句响应快得多。
select * from emp e,dept d where e.deptno =30 and d.deptno >10;

最好不要在WHERE子句中使用函或表达式,如果要使用的话,最好统一使用相同的表达式或函数,这样便于以后使用合理的索引。

SELECT *  FROM T1 WHERE  F1*2 = 100
 改成
 SELECT *  FROM T1 WHERE  F1 = 100/2
● 使用WHERE (NOT)EXISTS 来代替(NOT)IN子句,使用NOT EXISTS 子句可以有效地利用索引。
尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(NOT IN不能使用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高。
例子1:  
SELECT dname, deptno FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp); 
例子2
SELECT dname, deptno FROM dept WHERE NOT EXISTS (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno); 
明显的,2要比1的执行性能好很多。
因为1中对emp进行了全表扫描,这是很浪费时间的操作。而且1中没有用到emp的索引, 因为没有where子句。而2中的语句对emp进行的是缩小范围的查询。
 通过使用>=、<=等,避免使用NOT命令
如这个例子:
select * from employee where salary<>3000; 
对这个查询,可以改写为不使用NOT:
select * from employee where salary<3000 or salary>3000; 
虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。
 外部联接 + 的用法

外部联接+按其在=的左边或右边分左联接和右联接。若不带+运算符的表中的一个行不直接匹配于带+预算符的表中的任何行,则前者的行与后者中的一个空行相匹配并被返回。利用外部联接+,可以替代效率十分低下的 not in 运算,大大提高运行速度。例如,下面这条命令执行起来很慢:
select a.empno from emp a where a.empno not in
(select empno from emp1 where job=‘SALE’); 
索引倘若利用外部联接,改写命令如下:  
select a.empno from emp a left join emp1 b 
on a.empno=b.empno 
where b.empno is null 
and b.job=‘SALE’;

例如表少,但情况复杂的时候应该写如下语句:

select a.empno AS empno,

(select emp2.address from emp2 where a.id=emp2.id) AS address,

(select emp3.address1 from emp3 where b.id=emp3.id) AS address1

from emp a left join emp1 b on a.empno=b.empno 

where b.empno is null and b.job=‘SALE’

这样运行速度明显提高.

在查询时尽量少用格式转换

如用 WHERE a.order_no = b.order_no 
而不用 
WHERE TO_NUMBER (substr(a.order_no, instr(b.order_no, ’.’)-1) 
= TO_NUMBER (substr(a.order_no, instr(b.order_no, .’) - 1) 
Order by语句
索引ORDER BY语句决定了Oracle如何将返回的查询结果排序。Order by语句对要排序的列没有什么特别的限制,也可以将函数加入列中(象联接或者附加等)。任何在Order by语句的非索引项或者有计算表达式都将降低查询速度。
仔细检查order by语句以找出非索引项或者表达式,它们会降低性能。解决这个问题的办法就是重写order by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order by子句中使用表达式。

如必须使用排序操作,请遵循如下规则: 如结果集不需唯一,使用union all代替union。
IS NULL 与 IS NOT NULL

不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。
任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。

       SELECT子句中避免使用 ‘ *‘

            SELECT * FROM EMP

            应改为:

            SELECT COLUMN FROM EMP

       当在SQL语句中连接多个表时, 最好使用表别名并把别名加在每个列上

       其他

使用count(*)而不要使用count(column_name)。

避免困难的正规表达式LIKE通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _” 
即使在zipcode字段上建立了索引,也还是采用顺序扫描的方式。如果把语句改为

SELECT * FROM customer WHERE zipcode >98000

在执行查询时就会利用索引来查询,显然会大大提高速度。 
另外,以下语句也不会使用索引:

SELECT * FROM customer WHERE zipcode LIKE '[C-P]arsen'

SELECT * FROM customer WHERE zipcode LIKE 'parsen [^L]%'

SELECT * FROM customer WHERE zipcode LIKE '%parsen'