1.在进行多表关联时,多用 Where 语句把单个表的结果集最小化,多用聚合函数汇总结果集后再与其它表做关联,以使结果集数据量最小化。
2.在两张表进行关联时,应考虑可否使用右连接。以提高查询速度。
3.使用 where 而不是 having ,where是用于过滤行的,而having是用来过滤组的,因为行被分组后,having 才能过滤组,所以尽量用户 WHERE 过滤
4.使用 exists 而不用 IN 因为 Exists 只检查行的存在,而 in 检查实际值。
5.尽量不使用IN操作符:用 IN 写出来的 SQL 的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。但是用 IN 的 SQL 性能总是比较低,原因是:对于用 IN 的 SQL 语句 ORACLE 总是试图将其转换成多个表的连接,如果转换不成功则先执行 IN里面的子查询,再查询外层的表记录,如果转换成功就转换成多个表的连接。因此 不管理怎么,用 IN 的 SQL 语句总是多了 一个转换的过程。一般的 SQL 都可以转换成功。但对于含有分组统计等方面的 SQL 就不能转换了。因此在业务密集的SQL当中尽量不采用IN操作符。
6.尽量不使用NOT IN 操作符:此操作强烈推荐不使用,因为其不能应用表的索引。如遇这种情况,应该用 EXISTS ,NOT EXISTS 或者(外连接+判断为空)方案代替。
- 尽量不使用<> 操作符:不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。对于这种情况,可以用其它方式代替,如:A<>0 -> A>0 OR A<0
8.尽量不使用like 操作符遇到需要用到 LIKE 过滤的SQL语句,完全可以用 instr(字符查找函数) 代替,处理速度将显著提高。
9.union操作符:union在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录。最常见的是过程表与历史表union。如:select * from tb_test union select * from tb_test_h 这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。推荐方案:采用union ALL操作符替代union,因为union ALL操作只是简单的将两个结果合并后就返回。
10.SQL书写的影响:
同一功能同一性能不同写法SQL的影响,如一个SQL在A程序员写的为select * from tb_test;B程序员写的为select * from dlyx.tb_test;(带表所有者的前缀)C程序员写的为select * from DLYX.TB_TEST;(大写表名)D程序员写的为select * from DLYX.TB_TEST;(中间多了空格)以上四个SQL在ORACLE分析整理之后产生的结果及执行的时间是一样的,但是从ORACLE共享内存SGA9(是一块用于加载数据、对象并保存运行状态和数据库控制信息的一块内存共享区域,用来存放操作的数据库缓存数据字典等控制信息的内存区域,这块区域中的大多数内容都是共享存在,几乎所有的Oracle进程都会访问这块内存中的数据。在数据库实例启动时分配,当实例关闭时释放,每个实例都有自己的SGA区。SGA是占用内存最大的一个区域,同时也是影响数据库性能的重要因素)的原理,可以得出ORACLE对每个SQL都会对其进行一次分析,并且占用共享内存,如果将SQL的字符串及格式写得完全相同则ORACLE只会分析一次,共享内存也只会留下一次的分析结果,这不仅可以减少分析SQL的时间,而且可以减少共享内存重复的信息,ORACLE也可以准确统计SQL的执行频率。
11.采用函数处理的字段不能利用索引。
综上因为各个数据库及服务器性能情况不一样,很可能一个地方性能提升了,但另一个地方却下降了,ORACLE在SQL执行分析方面已经比较成熟,如果分析执行的路径不对首先应在数据库结构(主要是索引)、服务器当前性能(共享内存、磁盘文件碎片)、数据库对象(表、索引)统计信息是否正确这几方面分析。