Oracle SQL 性能优化技巧

1.用适合的ORACLE化器
     ORACLE
化器共有3

     ARULE (基于规则) bCOST (基于成本) cCHOOSE (选择)

     置缺省的化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各声明,如RULECOSTCHOOSEALL_ROWSFIRST_ROWS 你当然也在SQL或是会(session)级对行覆盖。

     了使用基于成本的化器(CBO Cost-Based Optimizer) 你必须经常运行analyze 命令,以增加数据中的统计信息(object statistics)的准确性。

     如果数据化器模式为选择(CHOOSE),那么实际化器模式将和是否运行analyze命令有 如果tableanalyze 化器模式将自CBO 反之,数据将采用RULE形式的化器。

在缺省情况下,ORACLE采用CHOOSE化器, 了避免那些不必要的全表(full table scan) 你必尽量避免使用CHOOSE化器,而直接采用基于规则或者基于成本的化器。


2.
访问Table的方式
     ORACLE
采用两种访问表中记录的方式:

     A 全表

          全表描就是序地访问表中记录ORACLE采用一次入多个数据(database block)的方式化全表描。

     B ROWID访问

          你可以采用基于ROWID访问方式情况,提高访问表的效率, ROWID包含了表中记录的物理位置信息。ORACLE采用索引(INDEX)实现了数据和存放数据的物理位置(ROWID)系。通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高。


3.
共享SQL
    
了不重解析相同的SQL句,在第一次解析之后,ORACLESQL句存放在内存中。这块位于系全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据共享。 因此,当你行一个SQL(被称一个游),如果它和之前的句完全相同, ORACLE就能很快得已被解析的句以及最好的行路径。ORACLE个功能大大地提高了SQL行性能并省了内存的使用。

     可惜的是ORACLE对简单的表提供高速(cache buffering)个功能并不适用于多表查询

     数据管理init.ora为这个区域置合适的参数,当个内存区域越大,就可以保留更多的句,当然被共享的可能性也就越大了。

     当你向ORACLE提交一个SQL句,ORACLE会首先在这块内存中找相同的句。里需要注明的是,ORACLE两者采取的是一种严格匹配,要达成共享,SQL句必完全相同(包括空格,行等)

     数据管理init.ora为这个区域置合适的参数,当个内存区域越大,就可以保留更多的句,当然被共享的可能性也就越大了。

     共享的句必须满足三个条件:

     A 字符的比 当前被行的句和共享池中的句必完全相同。

     B 两个句所指的象必完全相同:

     C 两个SQL句中必使用相同的名字的(bind variables)


4.
选择最有效率的表名(只在基于规则化器中有效)
     ORACLE
的解析器按照从右到左的FROM子句中的表名,因此FROM子句中写在最后的表( driving table)将被最先理。在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作表。当ORACLE理多个表 会运用排序及合并的方式接它。首先,描第一个表(FROM子句中最后的那个表)对记录进行派序,然后描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中索出的记录与第一个表中合适记录进行合并。

     如果有3个以上的表查询 那就需要选择交叉表(intersection table)表, 交叉表是指那个被其他表所引用的表。


5.WHERE
子句中的
     ORACLE
采用自下而上的序解析WHERE子句,根据个原理,表之接必写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必写在WHERE子句的末尾。


6.SELECT
子句中避免使用 ' * '
    
当你想在SELECT子句中列出所有的COLUMN,使用动态SQL列引用 '*' 是一个方便的方法。不幸的是,是一个非常低效的方法。实际上,ORACLE在解析的程中, 会将'*' 依次转换成所有的列名, 个工作是通过查询数据字典完成的, 意味着将耗更多的时间


7.
减少访问数据的次数
    
SQLORACLE在内部行了多工作:解析SQL句,估算索引的利用率,量,数据等等。由此可,减少访问数据的次数,就能实际上减少ORACLE的工作量。


8.
使用DECODE函数来减少时间
    
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。


9.
整合简单,无关联的数据库访问
    
如果你有几个简单的数据库查询语句,你可以把它整合到一个查询(即使它没有)


10.
除重复记录

11.TRUNCATE替代DELETE
    
除表中的记录时,在通常情况下, (rollback segments ) 用来存放可以被恢的信息。 如果你没有COMMITORACLE会将数据恢除之前的状(准确地是恢除命令之前的状况)

     而当运用TRUNCATE 段不再存放任何可被恢的信息。当命令运行后,数据不能被恢。因此很少的源被用,时间也会很短。


12.
尽量多使用COMMIT
    
只要有可能,在程序中尽量多使用COMMIT这样程序的性能得到提高,需求也会因COMMIT放的源而减少

     COMMIT放的源:

     A 段上用于恢数据的信息。

     B、被程序得的

     C redo log buffer 中的空

     DORACLE管理上述3种资源中的内部花


13.
记录条数
    
和一般的点相反,count(*) count(1)稍快,当然如果可以通索引索,索引列的数仍旧是最快的。例如 COUNT(EMPNO)


14.
Where子句替HAVING子句
    
避免使用HAVING子句,HAVING 只会在索出所有记录之后才对结果集过滤 理需要排序,总计等操作。如果能通WHERE子句限制记录的数目,那就能减少方面的开销


15.
减少表的查询
    
在含有子查询SQL句中,要特注意减少表的查询


16.
内部函数提高SQL效率。

17.使用表的(Alias)
    
当在SQL句中接多个表 使用表的名并把名前Column上。这样一来,就可以减少解析的时间并减少那些由Column引起的错误


18.
EXISTS替代IN
    
多基于基表的查询中,足一个条件,往往需要另一个表接。在这种情况下,使用EXISTS(NOT EXISTS)通常将提高查询的效率。


19.
NOT EXISTS替代NOT IN
    
在子查询中,NOT IN子句将行一个内部的排序和合并。 在哪情况下,NOT IN都是最低效的 (查询中的表行了一个全表遍)了避免使用NOT IN ,我可以把它改写成外(Outer Joins)NOT EXISTS


20.
用表接替EXISTS
    
通常来 采用表接的方式比EXISTS更有效率


21.
EXISTSDISTINCT
    
当提交一个包含一多表信息(比如部表和雇)查询时,避免在SELECT子句中使用DISTINCT 一般可以考EXIST

你可能感兴趣的:(Oracle SQL)