Oracle SQL 性能优化技巧整理

本文介绍了Oracle数据库中SQL查询的优化技巧,包括选择合适的优化器、改进表访问方式、共享SQL语句以及减少数据库访问次数等。同时,还探讨了Oracle内存结构,包括进程全局区(PGA)、用户全局区(UGA)和调用全局区(CGA)的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    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内存()----Process Memory详细信息
The Process Memory:
 
除了SGA(System Global Area)之外,Oracle使用下面三个全局区:
  The Process Global Area (
PGA)
  The User Global Area (UGA)
  The Call Global Area (CGA)
 很多人都搞不清楚PGAUGA两者之的区,实际上两者之的区跟一个程和一个会的区似的.尽管说进程和会一般都是一一的,实际上比个更复杂.一个很明的情况是MTS配置,往往会比程多得多.这种配置下,一个程会有一个PGA,一个会会有一个UGA.PGA所包含的信息跟会是无任何关联,UGA包含的信息是以特定的会话为.
 The PGA:
 程全局区(PGA即可以理解)Process Global Area,也可以理解Program Global Area.它的内存段是在程私有区(Process Private Memory而不是在共享区(Shared Memory它是个全局区意味着它包含了所有代).)有可能入的全局量和数据,但是它是不被所有程共享的.Oracle的服程都包含有属于自己的PGA,它只包含了本程的相特定信息.PGA中的构不需要由latches来保,其它的程是不能入到里面来访问.
 PGA包含的是有关进程正在使用的操作系统资源信息以及程的状信息,而其它的程所使用的Oracle的共享源是在SGA.PGA是私有的而不是共享的,个机制是有必要的,程死掉后可以把源清除和放掉.
 PGA包含两个主要区域:Fixed PGAVariable PGA或称PGA Heap. Fixed PGA的作用跟Fixed SGA似的,都包含原子(不可分的),小的数据构和指向Variable PGA的指.
  Variable PGA是一个堆.它的Chunks可以从Fixed Table X$KSMPP看得到,个表的构跟前面有提到的X$KSMSP是相同的.PGA包含了一些有 HEAPFixed Table的永久性内存,它跟某些参数的置有依赖关.些参数包含DB_FILES,LOG_FILES,CONTROL_FILES.
  The UGA:
  UGA(User Global Area)包含的是特定会的信息,有如下一些:
 所打的持和运行时间内的区域
 包的状信息,特定的
  Java
 可以用的ROLES
 ENABLE的跟踪事件
 起作用的NLS参数
 DBLINK
 的入口控制
 PGA,UGA也由两区:Fixed UGAVariable UGA,也称UGA HEAP. Fixed UGA包含了大70个原子,小的数据构和指向Variable UGA的指.
  UGA HEAP中的Chunks可以从它自己的会中通过查看表X$KSMUP得相信息,个表的构跟X$KSMSP是一.UGA HEAP包含了一些有fixed tables的永久性内存段,跟一些参数的置有依赖关.些参数有OPEN_CURSORS,OPEN_LINKS,MAX_ENABLE_ROLES.
  UGA在内存中的位置依于会的配置方式.如果会话连接的配置方式是用服器模式(DDS)即是一个会话对应一个,UGA是放在PGA中的.PGA,Fixed UGA是其中的一个Chunk,UGA HEAPPGA的一个子堆(Subheap).如果会话连接是配置共享服器模式(MTS), Fixed UGASHARED POOL中的一个Chunk,UGA HEAPSHARED POOL中的子堆(Subheap)
  The CGA:
 跟其它的全局区不同,Call Global Area是短性存在的.它只有在用数据期存在,一般是在对实例的最低级别才需要CGA,如下:
 分析一个SQL
 行一个SQL
 取出一个SELECT句的
 一个独的CGA递归调是需要的.SQL句的分析程中,数据字典信息的递归调用是需要的,SQL法分析,有在句的化期.PL/SQL块时SQL句的也是需要递归调用的,DML句的理触行也是需要递归调用的.
 不管UGA是放在PGA是在SGA,CGA都是PGA的一个子堆(Subheap).个事的一个重要推是在一个用的期是一个.于在一个MTSOracle数据库进开发时关一点的理解是很重要的.如果相,就得增加processes的数量以适应调用的增加.
 没有CGA中的数据,CALLS是没法工作的.实际上跟一次CALL的数据构一般都是放在UGA,SQL AREA,PL/SQL AREASORT AREA都必UGA,要在各CALLS要一直存在并且可用.CGA中所包含的数据构是要在一次CALL束后能够释放的.例如CGA包含了递归调用的信息,直接I/O BUFFER有其它的一些临时性的数据.
  Java Call Memory也是在CGA.一段内存比Oracle的其它内存段管理得更密集.它分成三个Space: Stack Space, New Space, Old Space.New SpaceOld Space中不再被参考使用的Chunks,根据它在使用期度及SIZE的不同,用的程中将被当成不用的Chunks收集起来.New Space Chunks很多次的不用的Chunks的反收集程中没有被收集的Chunks将会被放到Old Space Chunks.是在Oracle内存管理中唯一的一个物收集(garbage collection),其它的Oracle内存段都是Dead Chunks.
  Process Memory Allocation
 SGA不一的是,SGA例启之后SIZE就已是定下来的,PGASIZE是会增.使用malloc()或者sbrk()统调用来为进程增加堆数据段大小而使得PGASIZE的增.OS的新虚内存会被做PGA HEAP中的一个新的区被加到PGA中来.些区一般只几KB,如果有需要,Oracle将会分配上千个区.
 操作系统对每程的堆数据段的增是有限制的.大部分的情况是操作系的内存参数行限制(kernel parameter: MAXDSIZ),有一些情况它的缺省是可以以基准行修改的.于所有的,操作系统对整个虚内存也有一个系全局性的限制,个限制跟系SWAP SPACE.一旦超两个限制,Oracle程在行中会遇到ORA-4030错误.
  ORA-4030错误生一般不是因为每程的源限制而是因SWAP SPACE不足造成.问题可以使用操作系的一些选项SWAP SPACE的使用情况.另外,在一些操作系,Oracle包含了一个工具叫maxmem,它可以用来程可以被分配的堆数据段的最大SIZE以及哪一个限制是第一次超.
 如果问题的出是因SWAP SPACE不足,而且换页作非常繁而且,需要减少系的虚内存的使用,个可以通减少程数也可以通减少程的内存限制.如果换页动作不繁而且比,需要SWAP SPACE SIZE.
 
Process Memory Deallocation:
  Oracle堆的增比它的收要来得容易,当然它SIZE也是可以收.V$MYSTATV$SESSTAT视图,session统计信息session uga memorysession pga memory别显示了当前sessionUGAPGA的内存大小,包含内部的空.统计信息session uga memory session pga memory maxmax别显示了在session的生存期所使用得最大的UGA和最大的PGA.
  UGAPGA只有在特定的操作后才会收,些操作如一次磁排序的合并操作,或者用程序DBMS_SESSION.FREE_UNUSED_USER_MEMORY放内存.只有整个free heap extent会被父堆或者是程堆数据段,所以有一部分的内部free space在内存放后仍然存在于subheap.
 在大多的操作系统环境下,Oracle是不会减少程堆数据段也不会放虚内存并将其返还给操作系.所以从一个操作系看中,一个Oracle程将会把虚内存SIZEHWM而保留着.如果有必要,Oracle是会将一些没用的虚内存页换页出去的.为这个原因,Oracle程的虚内存的操作系统统计信息都是很理解的.所以一般用的是Oracle内部统计信息来代替使用操作系统计信息.
 程序DBMS_SESSION只能在.FREE_UNUSED_USER_MEMORY接是配置MTS模式的用才能使用.个最好是少点使用,它只放大的包的array量所占用的内存返还给Large Pool或者是Shared Pool.一般地,UGA HEAP的内存应该首先被,可以通指派新的空arrayarray量使用,也可以通过调用程序DBMS_SESSION.RESET_PACKAGE.
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值