Oracle优化规则
ORACLE在解析的过程中,会将'*' 依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。
删除表中全部数据时,可以使用TRUNCATE命令快速删除数据。
只要有可能,在程序中尽量多使用COMMIT,这样程序的性能得到提高,
需求也会因为COMMIT所释放的资源而减少。
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。
在含有子查询的SQL语句中,要特别注意减少对表的查询。例子:SELECT TAB_NAMEFROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECTTAB_NAME,DB_VERFROM TAB_COLUMNS WHERE VERSION = 604)
表之间关联消耗大,设计数据结构时需要考虑,使用中能尽量减少表的关联。
当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Colum上这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用EXISTS(或NOTEXISTS)通常将提高查询的效率。
索引用来提高检索数据的效率。
9.1避免在索引列上使用计算。
WHERE子句中,如果索引列是函数的一部分。优化器将不使用索引而使用
表扫描。
举例:
低效:SELECT… FROM DEPT WHERE SAL * 12 > 25000;
高效:SELECT… FROM DEPT WHERE SAL > 25000/12。
9.2避免改变索引列的类型。:
当比较不同数据类型的数据时,ORACLE自动对列进行简单的类型转换。因为内部发生的类型转换,将不会使用索引。为了避免ORACLE对SQL进行隐式的类型转换,最好把类型转换用显式表现出来。
9.3 使用索引时应注意:
某些SELECT语句中的WHERE子句不使用索引
(1)'!='将不使用索引。索引只能告诉什么存在于表中,而不能告诉什么不存在于表中。
(2) '||'是字符连接函数。函数会停用索引。
(3) '+'是数学函数。函数停用索引。
(4)如果检索数据量超过30%的表中记录数。使用索引将没有显著的效率提高。
(5)在特定情况下,使用索引也许会比全表扫描慢,但这是同一个数量级上的区别。而通常情况下,使用索引比全表扫描要块几倍乃至几千倍。
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。
低效: (索引失效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE ISNOT NULL;
高效: (索引有效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE>=0。
高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于,前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。
当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,然后在输出最终结果前进行排序。如果用UNIONALL替代UNION,这样排序就不是必要了,效率就会因此得到提高。
带有DISTINCT,UNION,MINUS,INTERSECT,ORDERBY的SQL语句会启动SQL引擎,执行耗费资源的排序(SORT)功能。DISTINCT需要一次排序操作,而其他的至少需要执行两次排序。通常,带有UNION,MINUS ,INTERSECT的SQL语句都可以用其他方式重写。
分区表对性能提升明显。当数据量超过一百万条时,应考虑使用分区表,可以根据需要使用range分区、list分区或者组合分区,使用分区表可以大幅缩短查询时间。
当对大数据量表进行查询、删除、插入、修改等操作时,可以根据资源情况,进行并行操作,可以提升相关操作的执行速度,oralce语法为并行提示parallel
大数据处理时,如果使用游标,处理时间与数据量成正比,此时应该减少游标的使用,理论上游标都可以替换为批量形式执行。
检查sql执行计划是否正确,cost是否合理,若不合理,需要调优。
优化业务流程,减少与数据库的连接和交互次数,在尽量少的数据库交互中得到所有信息。
程序中串行执行部分,如果可能,尽量拆分为更小的执行单元,执行单元之间并行执行,减少执行总时间。
Dblink访问大表,将消耗网络传输,同时影响整体执行计划,尽量少用。可以使用临时表落地。