Oracle彻底优化 - -
数据库系统和操作系统一样,在计算机上安装成功后,还需要进一步配置和优化,从而使其具有更强大的功能和运行在最佳状态。如果在设计阶段因为各种因素没有进行较为合理的配置和计划,那么就需要在后期对数据库系统进行优化。
数据库系统性能的优化,除了在设计阶段对其逻辑存储结构和物理存储结构设计进行优化,使之在满足需求条件下,时空开销性能最佳外,还可在运行阶段,采取一些优化措施,使系统性能最佳。本专题所讨论的性能优化主要指运行阶段的性能优化,即讨论如何使用Oracle所提供的优化手段来提高系统性能。大多数性能问题并不是一种孤立的症状,而是系统设计的结果,因此性能优化就集中在那些导致不可接受特征的同一的、固定的和潜在的问题上。优化是数据库设计中“计划”、“设计”、“监视”和“优化”四大步骤的最后一步。 除了用Oracle优化器来优化数据库的性能外,DBA还可通过优化Oracle的参数设置等手段来优化数据库的性能,对参数的细微优化便能影响系统整体性能。
为了有目的优化系统性能,首先应明确优化目标,然后再根据目标优化各种初始参数的设置,以达到更好效果。可有如下几个优化目标:
◆ 应用程序设计的优化
◆ 指定类型SQL语句的优化
◆ 内存使用的优化
◆ 数据存储、物理存储和逻辑存储的优化
◆ 网络通信量的优化
DBA可选定上述一个或多个目标来实施优化。性能优化主要是通过优化初始化参数来实现。本专题从以下几个方面来谈谈如何优化Oracle数据库,使其具有最佳性能。
(1)优化初始参数
(2)优化内存
(3)优化I/O
(4)优化资源争用
(5)其它参数优化
在进行数据库系统性能优化时,需要熟练掌握和了解一些可变参数。本文讨论了一些对系统性能有较大影响的参数。
(1)DML_LOCKS
该参数表明多少个用户,可同时能修改多少张表。例如:有三个用户同时修改二张表,则要求表上的总数为6。若置为0,则组织队列不起作用,其性能会稍有提高。使用该参数时不能用DROP TABLE、CREATE INDEX或显式封锁。
(2)LICENSE_MAX_SESSION
该参数指出允许并发用户会话的最大数。若此参数为0,则不能实施并发。若并发的用户会话数已达到此极限,则只有具有RESTRICTED SESSION权限的用户才能连接到服务器。
(3)LICENSE_MAX_USERS
该参数指出在一个数据库上可建立的最大用户数。当达到最大值时,便不能再建新用户,可改变此值以放松限制。在LICENSE_MAX_SESSION或LICENSE_MAX_USER为0时,则并发会话或任何用户都不能用。若对不同的实例,此参数不同时,则以第一个登录的数据库实例的参数为准。
(4)MAX_DUMP_FILE_SIZE
该参数指定操作系统中写跟踪文件的块的最大值。可用此值来限制跟踪文件的空间。
(5)OPEN_CURSORS
该参数指明一个用户进程能同时打开光标的最大数,它能限制每个用户进程占用的内存空间量。
(6)OPEN_LINKS
该参数指定并发连接到远程数据库的最大用户进程数。若同时引用多个数据库,则应该增大该值。例如:同时交替访问A、B和C三个数据库时,若OPEN_LINKS设置为2,则需花费等待连接时间。此参数只用于分布事务。若该参数设置为0,则不允许进行分布事务处理。
(7)PROCESS
该参数指定同时连接到Oracle服务器上的最大用户进程数。该参数值包括6个后台进程和一个登录,因此,该参数值为20,则只能有13或14个并发用户连接到服务器。
(8)ROW_LOCKING
该参数指定行封锁方式。若设置为“ALWAYS”,则在修改表时只实施行封锁。若设置为“INTENT”时,则行封锁只适用于SELECT FOR UPDATE,而在修改时实施表封锁。
(1)CHECKPOINT_PROCESS
该参数根据是否要求检查点而设置成TRUE或者FALSE。当所有缓冲区的信息写到磁盘时,检查点进程(CHPT)建立一个静态的点。在归档日志文件中做一个记号表示有一个检查点发生。检查点发生在归档日志转换的时候或当达到log_checkpoint_interval定义的块数的时候。当设置此参数为TRUE时,后台进程CHPT便可工作。在检查点期间内,若日志写进程(LGWR)的性能减低,则可用CHPT进程加以改善。
(2)DB_BLOCK_CHECKPOINT_BATCH
该参数的值设置得较大时,可加速检查点的完成。当指定的值比参数DB_BLOCK_CHECKPOINT_BATCH大时,其效果和指定最大值相同。
(3)DB_BLOCK_BUFFERS
该参数是在SGA中可作缓冲用的数据库块数。该参数决定SGA的大小,对数据库性能具有决定性因素。若取较大的值,则可减少I/O次数,但要求内存空间较大。每个缓冲区的大小由参数DB_BLOCK_SIZE决定。
(4)DB_BLOCK_SIZE
该参数表示Oracle数据库块的大小,以字节为单位,典型值为2048或4096。该值一旦设定则不能改变。它影响表及索引的FREELISTS参数的最大值。
(5)DB_FILES
该参数为数据库运行时可打开的数据文件最大数目。
(6)DB_FILE_MULTIBLOCK_READ_COUNT
该参数表示在顺序扫描时一次I/O操作可读的最大块数,该最大块数取决于操作系统,其值在4至16或者32是比较好。
(7)D1SCRETE_TRANSACTION_ENABLED
该参数实现一个更简单、更快的回滚机制,以改进某些事务类型的性能。 当设置为TRUE时,可改善某些类型的事务性能。
(8)LOG_ARCHIVE_BUFFER_SIZE
此参数的值依赖于操作系统,它与LOG_ARCHIVE_BUFFER 参数一起用于调整有归档日志的运行,使其运行速度尽量加快,但不能快到降低性能。仅当直接归档到磁带设备时才需要增加这些参数的值,重做日志缓冲区要等待归档日志缓冲区变得可用。
(9) LOG_ARCHIVE_BUFFER
该参数指定用于归档的日志时的缓冲区数。
(10) LOG_BUFFER
该参数指明分配给SGA中的日志缓冲区的字节数,该参数值较大时,可减少日志I/O的次数。对于繁忙的系统不宜采用大于或等于64K的值。缺省值-般为数据库块的4倍。
(11)LOG_CHECKPOINT_TIMEOUT
该参数指明两个检查点之间的时间间隔,若指定为0时,则说明不允许进行基于时间的检查点。
(12)LOG_CHECKPOINT_INTERVAL
该参数用来确定检查点进程的执行频率。这个数值设置成取检查点之前处理的重做缓冲区块的数量。
(13)LOG_FILES
该参数指定运行期间数据库可打开的日志文件数。若需要较大的SGA空间,而不需多个日志文件,则可减少该值。
(14)LOG_SIMULTANEOUS_COPIES
该参数是日志缓冲区副本闩锁的最大数,为同时写日志项所用。为提高性能,可设置此参数为两倍的CPU数,对单进程系统,该值多数设置为0,此时断开闩锁。
(15)LOG_SMALL_ENTRY_MAX_SIZE
该参数与LOG_SIMULTANEOUS_COPIES参数配合使用。若日志项大于此项,则在给缓冲区分配空间并获得日志复制闩锁之后,用户进程释放日志复制闩锁。
(16)OPTIMIZRER_MODE
若该参数的值为RULE,则ORACLE优化器选择基于规则的优化;若设置为COST,并且在数据字典中存在有统计信息,则优化器选择基于代价的优化方法进行优化。
(17)SEQUENCE_CACHE_ENTRIES
该参数指明在SGA中可进行高速缓存的序列数,用于直接存取。该高速缓存区是基于最近最少使用(LRU)的算法进行管理的。若此值设置得较高,则可达到较高的并发性。
(18)SEQUENCE_CACHE_HASH_BUCKETS
该参数用于加速查看高速缓冲区最近请求的最新序列的桶式地址数,每个桶式地址占8个字节。高速缓冲区以散列表排列,该参数应为质数。
(19)SERIALIZEABLE
此参数用于保证重复读的一致性。当它设置为TRUE时,查询可保证表级读一致,以防止在此查询提交之前的修改。
(20)SHARED_POOL_SIZE
该参数指定共享池的大小,其中包括共享光标及存储过程。在多用户系统中,较大的SHARED_POOL_SIZE值可改善SQL语句的执行性能,但较小的值可节省内存。
(21)SMALL_TABLE_THRESHOLD
该参数决定SGA中用于扫描的缓冲区的数目,若表的数目小于该值,则该表可整个地读入高速缓存区。若表大于该值,则立即重用该缓冲区。一般用缺省值可使性能最好。
(22)SORT_AREA_TETAINED_SIZE
这是会话内存的最大数量,用于内存排序。当从排序空间提出最后-行时,便释放该内存。若排序要较大的内存,则分配一临时段,排序便可在盘上进行。用于排序的最大总量可由SORT_AREA_SIZE指定,而不用此参数。可以分配同样大小的多个排序空间,不过一般对于复杂的查询才需要。
(23) SORT_AREA_SIZE
该参数用于指定进行外排序(磁盘)时所需PGA内存的最大数量,以字节为单位。当排序行写入磁盘时,该内存被释放。增大该参数的值,可改进排序效率。一般不调整该参数,除非排序量很大时才调整。
(24) SORT_SPACEMP_SIZE
该参数仅在排序量很大时才调整该参数。可用下式设置该参数,使排序能最佳地使用盘空间:
[(total_sort_bytes)/(SORT_AREA_SIZE)]十64
其中,total_sort_bytes为:
(number_of_records)*[sum_of_aver_average_column_sizes+(12*number of(al)]
(25)SQLTRACE
该参数设置为TRUE时,便可跟踪,以获得改善性能的信息。因为跟踪会增加开销,所以一般仅在收集信息时才置为TRUE。在实际使用时,可用ALTER SESSION命令覆盖它。
(26)TRANSACTION
该参数设置并发事务的最大数。若此值较大,则需增加SGA空间和分配的回滚段数量。缺省值大于PROCESS时,可允许递归事务。
由于0racle的内存结构需求与应用密切相关,所以内存结构优化应在SQL语句和应用程序优化之后以及输入/输出(I/O)优化之前进行。而且首先要优化操作系统,并在处理共享池前考虑私有SQL和PL/SQL区。
SGA是对数据库数据进行快速访问的一个系统全局区,其大小在实例启动时被确定。若SGA本身需要频繁地进行释放、分配,则不可能达到快速访问数据的目的。因此为了优化系统性能,应确保SGA全部被驻留在实际内存中,而不应采用虚拟内存,以免使整个系统性能下降。
SGA是Oracle为一个实例分配的一组共享内存缓冲区。它包含该实例的数据和控制信息。如果有多个用户同时与同一个实例相连接时,则其SGA中的数据可为多个用户共享,所以也叫它共享全局区。SGA在实例启动时被自动分配,当实例关闭时被收回。SGA中的数据和控制信息可被多个进程所使用,但只能由几个持殊进程能对其进行写操作。SGA中所包含的存储区根据其存放的信息类型大致可分为“数据库缓冲存储区”、“日志缓冲区”、“共享池”和“请求和响应队列”四大区域。
查看SGA大小
用户可以通过两种命令方式来查看SGA的大小。
(1)使用“SHOW SGA”命令
说明:用户可以连接到Sever Manager和数据库,然后执行“SHOW SGA”命令来查看SGA的大小。如果数据库实例没有启动,那么使用“SHOW SGA”命令将会报错。
(2)使用“SELECT * FROM V$SGA;”查询试图命令
说明:使用“SELECT * FROM V$SGA;”要在“SVRMGR>”提示符下。
预装SGA
可以在init.ora文件中将参数PRE_PAGE_SGA的值设为“yes”,而将SGA预装到物理内存中,即设置PRE_PAGE_SGA=yes。
要优化专用的SQL区及PL/SQL区,就必须知道是否有不必要的语法分析调用,用户必须尽量少的调用Parse。如果有过多的不必要的语法分析调用,就应当设法减少它。
可用跟踪功能来为每个SQL语句输出跟踪信息,以检测其语法分析步的统计数字count。若分析步的count统计值与执行步的count统计值非常接近,则应减少语法分析调用。
减少语法分析调用的方法是通过所用的应用开发工具(如PRO*C、OCI和SQL*Forms等)来控制语法分析调用以及分配和释放专用的SQL区的频率,例如:在用PRO*C时,可用HOLD_CURSOR、RELEASE_CURSOR以及MAX_OPENCURSOR参数来控制专用SQL区。在使用OCI时,可使用OSQL3或OPARSE调用来为SQL语句分配专用SQL区,用OCLOSE调用关闭光标和释放专用SQL区。在使用SQL *Forms时,同样也可控制是否重用专用SQL区:可在触发器级、Form级或在运行时减少语法分析调用,以减少或重用专用SQL区。
日志缓冲区也称为重做日志缓冲区,它包含所有变化了的数据块。这些变化的数据块通过Oracle日志书写进程以一种邻接的方式写到重做日志文件中。
(1)获取缓冲区活动情况
优化日志缓冲区时,首先应了解缓冲区的活动情况。这对通过查询动态性能表(需有SELECT ANY TABLE特权)V$SYSSTAT来获得。
SVRMGR> select sum(value)"Redo Buffer Waits" from v$sysstat
2> where name='redo log space wait time';
(2)计算日志缓冲区的申请失败率
数据库管理员可以通过执行下述语句:
SQL>select name,value from v$sysstat where name in ('redo entries','redo log space requests');查看日志缓冲区的使用情况。查询出的结果可以计算出日志缓冲区的申请失败率。
申请失败率=requests/entries。申请失败率应该接近于0,否则说明日志缓冲区开设太小,需要增加ORACLE数据库的日志缓冲区。
(3)优化日志缓冲区
如果重做缓冲区的等待大于零,进程就要等待重做日志缓冲区的空间变成可用。此时就会影响数据库的性能。可以通过逐步提高init.ora中参数LOG_BUFFER的值来达到优化日志缓冲区的目的。在增加LOG_BUFFER的值时,可通过查询动态性能表来了解和检查日志缓冲区的活动情况。
共享池由库高速缓存、字典高速缓存和SQL区组成。整个共享池的大小由参数SHARED_POOL_SIZE确定。共享池的优化主要考虑库高速缓冲区、数据字典高速缓冲区以及会话期间信息的优化。
要优化库高速缓冲区,必须首先了解该缓冲区的活动情况。库高速缓冲区的活动统计信息保留在动态性能表V$LIBRARYCACHE中。优化时应使数据字典高速缓存里的内存数据库块尽可能多。
(1)确定库高速缓存的性能
通过查询V$LIBRARYCACHE表(需有SELECT ANY TABLE特权)来了解其活动情况,以决定如何优化。例如:
SQL>SELECT SUM(pins),SUM(reloads) FROM V$LIBRARYCACHE;
说明:动态性能表V$LIBRARYCACHE中包含有NAMESPACE、PINS和RELOAD等列。其中NAMESPACE列反映了SQL语句及PL/SQL块的库缓冲区的活动,其值可能是‘SQL AREA’,‘TABLE/PROCEDURE’,‘BODY’和‘TRIGGER’等;而PINS和RELOADS列给出执行调用时的错误信息。PINS列给出SQL语句、PL/SQL块及被访问对象定义的总次数;RELOADS给出SQL语句或PL/SQL块的隐式分析或对象定义重装载时在库程序缓冲区中发生的错误。
(2)查看reloads和pins的比率
可以使用以下查询语句来查看reloads和pins的比率:
SELECT(SUM(reloads)/SUM(pins))×100“Library Cache Ratio”FROM V$LIBRARYCACHE;
用户必须保证reloads和pins的比率尽可能低,其值应低于1%,若RELOADS/PINS>1%,则应给缓冲区分配附加的存储及写等同的SQL语句,使SQL语句与PL/SQL块共享一个共享SQL区,这样可减少错误。如果库高速缓冲区无错误,则可设置初始化参数CUTSOR_SPACE_FOR_TIME为TRUE,以加速执行调用。这可使性能稍有改善。若每个用户可用的专用SQL区不足时,则不要将CUTSOR_SPACE_FOR_TIME设置为TRUE。
(3)优化库高速缓存区
优化库高速缓存时,可以通过增加init.ora文件中SHARED_POOL_SIZE或OPEN_CURSORS的参数值而达到满意的优化比率。
数据字典缓冲区在功能上与库高速缓存类似,但主要用于Oracle字典高速SQL语句。要优化数据字典缓冲区,也必须先查看数据字典缓冲区的使用情况及效果,然后依此来进行优化。数据字典缓冲区的使用情况记录在动态性能表V$ROWCHACHE中,其中有如下几列:
PARAMETER:记录某类特写数据字典项的统计,其值以‘de_’开始,例如某文件描述的统计为‘de_files’。
GETS:是对相应项请求次数的统计。
GETTMISSES:是引起缓冲区出错的数据请求次数。
可用如下语句来查询V$ROWCHACHE表:
SQL>SELECT (SUM(getmisses)/SUM(gets))*100 ”DaTa Dictionary Cache Ratio”FROM V$ROWCHACHE;
对于贫繁访问的数据字典缓冲区,GETMISSES与GETS之比要小于10%到15%。若大于此百分数时,则应考虑增加数据字典缓冲区的容量,即要增加SHARED_POOL_SIZE或者DB_BLOCK_BUFFERS初始化参数的值。
使用多线索服务器时共享池的优化
在多线索服务器结构中,会话期信息被存放在共享池中,它包括SQL专用区和排序区。在使用多线索服务器时,要增大共享池,以满足需要。这也可通过增加SHARED_POOL_SIZE的参数值来实现。
可通过查询(要求有SELECT ANY TABLE特权)动态性能表V$SESSTAT来衡量会话信息的多少。例如:
SQL>SELEC SUM(value) ||’bytes’ ”Total memory for all session”
2>FROM V$SESSTAT
3>WHERK name=‘session memory’;
SQL>SELECT UM(value)|| ‘bytes’ “Total max men for all sessions”
2>FROM V$SESSTAT
3>WHERE name=‘max session memory’;
其中,“session memory”是分配给会话的内存字节数;“max session memory”是分配给会话的最大内存字节数。
优化缓冲区
(1)获取缓冲区活动情况
为了优化缓冲区,首先应了解缓冲区的活动情况。这可以通过查询动态性能表(需有SELECT ANY TABLE特权)V$SYSSTAT来获得。
SVRMGR> select name ,value from v$sysstat
2> where name in('db block gets','consistent gets','physical reads');
NAME VALUE
db blockgets 3437
consistent gets 30500
physica reads 1963
3 rows selected.
其中,“db block gets”和“consistent gets”的值是请求数据缓冲区中读的总次数。“physical reads”为请求数据时引起从盘中读文件的次数。
从缓冲区读的可能性的高低称为缓冲区命中率。它可用如下公式计算:
Hot Ratio=1-(physical reads/(db block gets+consistent gets)
缓冲区命中率越高,其速度就越快。如果命中率低于60%或70%时。则应增加缓冲区(即DB_BLOCK_BUFFERS),以改进性能。根据公式可以计算出本例中的Hot Ratio=1-(1963/(3437+30500)=92%。 如果缓冲区的命中率很高,希望在保持良好性能下适当减少缓冲区,这时可减少DB_BLOCK_BUFFERS的值,其最小值为4。
I/O优化的目的是解决I/O瓶颈问题,I/O的优化必须在内存优化之后进行,可以通过减少磁盘争用、有效分配数据块空间和避免动态空间管理三个方面来优化I/O。
V$FILESTAT视图提供有关物理读写的信息。物理I/O针对磁盘,逻辑I/O针对内存。如果有多个进程同时访问同-磁盘,就产个磁盘争用。
监控Oracle的磁盘活动
要解决磁盘争用,首先应该知道磁盘的活动情况,确定是否发生争用。这可以通过查询动态性能表(需有SELECT ANY TABLE特权)V$FILESTAT和V$DATAFILE来确定。例如:
SQL>SELECT Name,phyrds,phywrts
2>FROM V$DATAFILE df,V$FILESTAT fs
2>WHERE df.file#=fs.file#;
其中:
◆ phyrds:记录从盘上读每个数据库文件的次数。
◆ phywrts:记录往盘上写数据库文件的次数。
一个盘上总的I/O次数是该盘上所有数据库文件的phyrds和phywrts之和。必须把物理读写的总量控制在用户硬件和操作系统的最优限制内。
监控操作系统磁盘的活动
在Windows 2000 Server中可以通过“性能”工具来监控磁盘的活动,对VMS和Unix多数磁盘进行每秒40次以上的I/O是过度的,应当给予调节。
分布I/O以解决磁盘争用
(1)存放重做日志文件
重做日志文件是顺序写入磁盘的,所以尽量不要将重做日志文件跟数据文件存放在同一个磁盘上。如果不得不将数据文件跟重做日志文件存放在同一个磁盘上,那么该盘空间不应该属于SYSTEM表空间、RBS表空间,以及其它如DATA和INDEX表空间。它们都会直接导致与重做日志文件之间的争用,而且还会有增加写入日志数据库读写速度的可能性。
(2)存放档案日志文件
在进行大量数据事务处理的时候,数据库选择归档功能将会导致其与重做日志磁盘间的争用。而且当档案重做日志文件出现空间不够时,将会引起数据库的冻结。所以档案日志文件不能与SYSTEM表空间、RBS表空间或INDEX表空间段存储在同一设备上,也不能与任何联机重做日志文件存放在同一设备上。它只允许与一些小的、静态的文件存放到一起。
(3)存放数据代码文件
为了减少数据库文件和数据库代码之间的争用,应避免将数据库文件作为代码文件而放在同一磁盘中。如果数据文件不得不放在同一磁盘设备中,那么应当将最不常用的数据文件放在那儿。
(4)减少非Oracle文件的I/O
(5)优化DBWR进程争用
数据库写进程(DBWR)、日志写进程(LGWR)与归档进程(ARCH)三种后台处理进程可以空闲存取磁盘上的数据库文件。这三个进程之间常因同时读写争用而导致I/O争用,而DBWR进程还有自我争用发生的可能。通过对DBWR赋值可以有效的解决DBWR的自我争用问题。
通常在操作系统中为每个实例创建多个DBWR进程,并通过初始参数DB_WRITERS来确定DBWR的个数。建议将赋值在n与2n之间,这里的n是指磁盘的个数。如果赋值不能很好的解决DBWR的内部争用,可以通过异步I/O来减少DBWR的内部争用。由于I/O进程的执行都是并行的,所以异步的I/O仅需一个DBWR即可解决问题。
(6)表数据存放策略
将大表的数据划分成若干小部分,并将这些部分存储在不同磁盘的不同数据文件中。用create tablespace创建表空间,在datafile子句中指定数据文件,每个文件应在不同的盘上。如我们需要在三个磁盘上存放数据文件,可使用如下代码:
create tablespace trip
datafile 'file_on_disk_1' size 500k,
'file_on_disk_2' size 500k,
'file_on_disk_3' size 500k;
(7)指定表空间和表大小
用“create table”创建表,在tablespace子句中指定表空间,在storage子句中指定表的大小,如以下SQL语句:
create table striptab (
……
Tablespace strip 1500k
Storage (initial 495k next 495k minextent 5 pctincreate 0);
(8)清除其它的磁盘I/O
因数据库中的数据被存放在数据块中,因此如何分配数据块中的空间将直接影响其存取性能。
当用update语句更新一行数据时,可能使该行的数据增加,从而使其在一个数据块内容纳不下。这时,Oracle就寻找能容纳下该行的数据块,如果能找到这样的块,便把该行全部存入新块中(这称为行移动)。如果找不到能容纳该整行的数据块,则把该行切成若干片,然后把每一片分别存放在一个数据块中,于是这样的行被存放在多个数据块中,这种行称为链接行。查询一个链接行则需要多次I/O操作,从而产生I/O瓶颈,这将降低数据的存取性能。
解决上述问题的办法是,使用带list chained rows选项的analyze命令来标出表或集中那些移动或链接的行,并将其集中在一个输出表中。对于这些输出表中的链接行,可增加其数据块的大小,以提高数据存取性能。
减少在已有表中的迁移和链接行的具体步骤如下:
(1)用analyze命令收集信息:
analyze table *** list chained rows;
(2)查询输出表:
select * from chained_rows where table_name='test_chain';
(3)消除迁移行:
创造与已有表有相同列的中间表来持有迁移行和链接行:
create table int_***
as seelct * from *** where rowid in (select head_rowid from chained_rows where table_name='***');
从已有表中删除迁移行和链接行:
delete from *** where rowid in (select head_rowid from chained_rows where table_name='***');
把中间表中的行插入已有表中:
insert into *** select 8 from int_***;
撤消中间表:
drop table int_***;
(4)从输出表中删除第1步收集的信息:
delete from chained_rows where table_name='***';
(5)再次使用analyze命令,并查询输出表;
(6)在输出表中出现的任何行是链接行,可增加数据块长度。
避免动态扩大段
一旦一个表或回滚段被建立,便在数据库中为其数据分配空间,此空间叫段。在数据操作过程中,其数据可能不断增长,而使其原分配的空间容纳不下。在这种情况下,Oracle就要为其扩大段空间(这叫动态扩大段),动态的扩大段将降低性能。可使用如下语句来检测是否出现动态扩大段:
SQL>Select name, value from V$sysstat where name='recursive calls';
如果检测出有动态扩大段,则应为其分配一个较大的范围,以避免或减少出现段的动态扩大。
避免回滚段中动态空间管理
在动态空间管理时也要尽量避免回滚段的动态管理。回滚段的大小会影响到系统性能,应当使它足够大,以便能容纳下事务的回滚段。可用set transaction命令来为事务分配一个合适的回滚段,如:
set transaction use rollback segment ***;
可采用以下三种方法来处理在动态空间管理时所出现的回滚段:
(1)对于长查询或长事务应当分配一个较大的回滚段,以提高性能。
(2)在同一个应用中同时运行的多个副本,不能共用同一个回滚段,以免出现回滚段争用。
(3)对于频繁更改,但更改数据量较小的并发联机事务处理,可采用较小的回滚段以加快缓冲区中数据的存取。
要减少回滚段的争用,首先需检查是否出现争用。对含有回滚段块的缓冲区的争用也会影响到对回滚段的争用。这可以通过查询动态性能表V$WAITSTAT来检测是否存在对回滚段的争用(需有SELECT ANY TABLE持权),例如:
SQL>SELECT class,count
2>FROM V$WAITSTAT
3>WHERE class IN('system undo header','system undo block',
4>'undo header','undo block');
其中参数含义如下:
◆ system undo header:对含有SYSTEM回滚段标题块的缓冲区的等待次数。
◆ system undo block:对含有SYSTEM回滚段非标题块的缓冲区的等待次数。
◆ undo header:对含有非SYSTEM回滚段标题块的缓冲区的等待次数。
◆ undo block:对含有非SYSTEM回滚段非标题块的缓冲区的等待次数。
如果任何等待次数大于总请求数的1%,则应创建更多的回滚段来减少竞争,可以周期性地检查这些统计数字,并将它与总的请求数据的次数作比较。总的请求数据次数可用如下语句求出:
SQL>SELECT SUM(value)
2>FROM V$SYSSTAT
3>WHERE name IN('db block gets','consistent gets');
减少回滚段争用的办法是为其建立适当数量的回滚段。表1给出了建立回滚段的参考数。
对多线索服务器进程的争用主要表现在对调度进程和共享服务器进程的争用。
减少调度进程的争用
对该进程的争用主要表现在调度进程占用率高及等待响应时间的增长方面。可通过查询动态性能表V$DISPATCHER(需有SELECT ANY TABLE特权)来检查争用情况,例如:
SQL>SELECT network "protocol",
2>SUM(busy)/(SUM(busy)+SUM(idle)) "Total Rate"
3>FROM V$DISPATCHER GROUP BY network;
其中V$DISPATCHER表中的idle和busy列的含义如下:
◆ idle:表示1%秒单位时间内调度进程的空闲时间。
◆ busy:表示1%秒单位时间内调度进程的占用时间。
DEC net分发进程接近0.5%时间是忙的,TCP分发进程接近3%时间是忙的。若占用率超过50%,则应该用增加调度进程的网络协议来改善性能。若要检查等待响应时间的增长情况,可通过查询动态性能表V$QUEUE(需有SELECT ANY TABLE特权)来检查。例如:
SQL>SELECT network "protocol",
2>DECODEE(SUM(totalq),0,'No Responses'),
3>SUM(wait)/SUM(totalq)||
4>'hundredths of seconds,"Average Wait Time Per Response"
5>FROM V$QUEUE q,V$DISPATCHER d
6>WHEEE q.type='DISPATCHER' AND q.paddr=d.paddr
7>GROUP BY network;
其中表V$QUEUE中的wait和totaq列的含义如下:
◆ wait:它表示1%秒单位时间内所有已在队列中等待响应的时间。
◆ totalq:表示在队列中的总的响应次数。
可通过以下办法来增加调度进程:
(1)用SQL * DBA的“Configure Multi-Threaded Dipatchers”对话框。
(2)用具有MTS_DISPATCHER参数的ALTER SYSTEM命令。
调度进程的总数由初始化参数MTS_MAX-DIPATCHER限制,在增加调度进程之前需要增加该参数,缺省值为5,最大值依赖操作系统。
减少共享服务器进程的争用
要减少共享服务器进程的争用,首先需确定是否有争用。请求队列中请求等待时间的增长反映对共享服务器进程的争用。这可以通过查询动态性能表V$SQUEUE(需有SELECT ANY TABLE特权)来确定是否有争用。查询语句的格式如下:
SQL>SELECT network "protocol", DECODE(totalq,o,'No Requests',
2>wait/totalq||,'hundreadths of seconds',) "Average Wait Time Per Requests"
3>FROM V$QUEUE
4>WHERE typc='COMMON';
其中表V$QUEUE中的wait和totalq列的含义如下:
◆ wait:队列中1%秒单位时间内所有请求的等待时间。
◆ totalq:是队列中请求的总数。
用如下的查询可以确定有多少个服务器进程在运行:
SQL>SELECT COUNT(*) "Shared Server Proccess"
2>FROM V$ SHARED_SERVERS
3>WHERE status!='QUIT';
增加共享服务器进程是由Oracle自动完成的。所以您不必显式地增加服务器进程。但是,当服务器进程的数量增加到参数MTS_MAX_SERVER所限制的数量时,如果还需增加,就必须修改MTS_MAX_SERVERS的值。此参数的缺省值为20,最大值依赖于操作系统。
无论是由Oracle自动增加服务器进程或是显示地增加共享服务器进程都可采用如下办法来改善性能:
(1)设置合适的MTS_MAX_SERVERS参数;
(2)用SQL * DBA的“Configure MuIti-Threaded Servers”对话框;
(3)用具有MTS_SERVERS参数的ALTER SYSTEM命令运行时执行:
alter system.mts_dispatchers
减少日志缓冲区空间的争用
日志缓冲区的争用将完全抑制数据库的性能,因此要设法减少它。日志空间请求反映了用户进程等待日志缓冲区空间的次数。所以可通过查问动态性能表V$SYSSTAT(需有SELECT ANY TABLE特权)来确定是否争用日志缓冲区空间。该查询语句的格式如下:
SQL>SELECT name, value
2>FROM V$SYSSTAT
3>WHERE name='redo log space requests';
日志空间的请求值应接近于0,否则需增加初始化参数LOG_BUFFER的值,以增加空间、减少争用。
减少日志缓冲区闩锁的争用
对日志缓冲区的访问由闩锁(latches)调控。闩锁分为日志分配闩锁和日志拷贝闩锁两类。
当多个用户同时频繁地访问日志缓冲区时,就可能引起对日志缓冲区闩锁的争用,从而降低性能。Oracle将所有闩锁的活动记录在动态性能表V$LATCH中。有SELECT ANY TABLE特权的用户可以查询它,以了解是否有争用发生。查询语句如下:
SQL>SELECT name,gets,misses,iddediate_gets,iddediate_miss
2>FROM V$LATCH l,V$LATCHMANE ln
3>WHERE ln.nome IN('redo allocation','redo copv')AND ln.latch #=1.latch #;
其中:
◆ willing_to_wait:对闩锁的请求种类之一。
◆ iddediate:对闩锁的请求种类之二。
◆ gets:表示对闩锁的willing_to_wait请求成功的次数。
◆ misses:表示对闩锁的willing_to_wait请求不成功的次数。
◆ iddediate_gets:表示对每个闩锁立即请求成功的次数。
◆ iddediate_miss:表示对每个闩锁立即请求不成功的次数。
要减少日志分配闩锁的争用就需使单个进程持有闩锁的时间最短,要减少此时间又应减少在日志闩锁上的拷贝,即减少参数LOG_SMALL_ENTRY_MAX_SIZE的值。
要减少日志拷贝闩锁的争用,一是观察其争用情况,增加闩锁,即增加LOG_SIMULTANEOUS_COPIES的值;二是减少持有闩锁的时间,即在获得日志拷贝闩锁之前,就迫使Oracle用户进程事先建立日志项。事先建立的所有日志项的大小都要小于参数LOG_ENTRY_PREBUILD_THRESHOLD,要事先建立日志项就要增加参数LOG_ENTRY_PREBUILD_THRESSHOLD的值。
排序是一项花销很大的操作,而且对性能的影响程度也较大,因此使大部分排序在内存中完成,而不是在磁盘上进行,这是至关重要的。
识别排序量的大小,就是要确定内存中排序的量和磁盘上排序的量,可用如下语句查询:
SQL> select name ,value from V$SYSSTAT where upper(name) in ('sorts(memory)','sorts(disk)');
其中“sorts(memory)”选项表示不需要磁盘I/O,选项“sorts(disk)” 表示需要磁盘I/O。如果用户认为在磁盘上的排序意义较大,可以增加init.ora文件SORT_AREA_SIZE参数的设置值。
当要改进查询的性能时,索引是最便捷的,常常也是最好的技术。多数新应用程序的存取速度问题是由于缺少合适的索引。使用索引可以使性能发生巨大的变化,而且确定需要什么样的索引也相对简单,只需要考察您的SQL语句,看WHERE子句中您用了什么内容。
对待索引的建立要特别谨慎,因为索引要占用磁盘空间。如果索引同表本身的大小差不多,那就不能从索引得到多少好处。索引还要对表的更新、插入和删除的性能产生影响。除了这几点之外,索引是改进查询性能的最简单、最有效的方法,尤其是当您总是对几个关键字字段进行搜索时,这种方法最合适。
索引建立要花费大量时间,可以使用ALTER INDEX REBUILD来创建新索引,这比其删除和重建索引要迅速得多。如果用户的数据已经排序,在构建索引时使用NOSORT选项,如:
SQL>ALTER INDEX emp_primary_key REBUILD;
SQL>CREATE INDEX myindex ON emp(ename) NOSORT;
CPU是服务器的一项重要资源,服务器良好的工作状态是在工作高峰时CPU的使用率在90%以上。如果空闲时间CPU使用率就在90%以上,说明服务器缺乏CPU资源;如果工作高峰时CPU使用率仍然很低,说明服务器CPU资源还比较富余。
查看CPU使用率
使用操作相同命令可以看到CPU的使用情况,一般Unix操作系统的服务器,可以使用“sar u”命令查看CPU的使用率,Windows NT操作系统的服务器,可以使用性能管理器来查看CPU的使用率。
查看数据库使用CPU的时间
可以通过查看V$SYSSTAT数据字典中“CPU used by this session”统计项得知Oracle数据库使用的CPU时间,查看“OS User level CPU time”统计项得知操作系统的用户态下CPU时间,查看“OS System call CPU time”统计项得知操作系统的系统态下CPU时间,操作系统总的CPU时间就是用户态和系统态时间之和。如果Oracle数据库使用的CPU时间占操作系统总的CPU时间90%以上,说明服务器CPU基本上被Oracle数据库使用着。反之,则说明服务器CPU被其它程序占用过多,Oracle数据库无法得到更多的CPU时间。
数据库管理员还可以通过查看V$SYSSTAT数据字典来获得当前连接Oracle数据库各个会话占用的CPU时间,从而得知什么会话耗用服务器CPU比较多。出现CPU资源不足的情况是很多的,SQL语句的重解析、低效率的SQL语句、锁冲突都会引起CPU资源不足。
查看SQL语句的解析情况
数据库管理员可以执行下述语句来查看SQL语句的解析情况:
SELECT * FROM V$SYSSTAT
WHERE NAME IN
('parse time cpu', 'parse time elapsed', 'parse count (hard)');
这里“parse time cpu”是系统服务时间,“parse time elapsed”是响应时间,用户等待时间waite time = parse time elapsed - parse time cpu。
由此可以得到用户SQL语句平均解析等待时间=waite time / parse count。这个平均等待时间应该接近于0,如果平均解析等待时间过长,数据库管理员可以通过下述语句来发现是什么SQL语句解析效率比较低。
SELECT SQL_TEXT, PARSE_CALLS, EXECUTIONS FROM V$SQLAREA
ORDER BY PARSE_CALLS;
程序员可以优化这些语句,或者增加Oracle参数SESSION_CACHED_CURSORS的值。
查看低效率的SQL语句
数据库管理员还可以通过下述语句查看低效率的SQL语句,优化这些语句也有助于提高CPU的利用率。
SELECT BUFFER_GETS, EXECUTIONS, SQL_TEXT FROM V$SQLAREA;
查看数据库的冲突情况
数据库管理员可以通过V$SYSTEM_EVENT数据字典中的“latch free”统计项查看Oracle数据库的冲突情况,如果没有冲突的话,latch free查询出来没有结果。如果冲突太大的话,数据库管理员可以降低spin_count参数值,来消除高的CPU使用率。
SQL语言是一种灵活的语言,相同的功能可以使用不同的语句来实现。但是语句的执行效率是很不相同的,程序员可以使用EXPLAIN PLAN语句来比较各种实现方案,并选出最优的实现方案。总得来讲,程序员写SQL语句需要满足考虑如下规则:
(1)尽量使用索引。试比较下面两条SQL语句:
◆ 语句A
SELECT dname, deptno FROM dept WHERE deptno NOT IN
(SELECT deptno FROM emp);
◆ 语句B
SELECT dname, deptno FROM dept WHERE NOT EXISTS
(SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
这两条查询语句实现的结果是相同的,但是执行语句A的时候,Oracle会对整个emp表进行扫描,没有使用建立在emp表上的deptno索引;执行语句B的时候,由于在子查询中使用了联合查询,Oracle只是对emp表进行的部分数据扫描,并利用了deptno列的索引。所以,语句B的效率要比语句A的效率高一些。
(2)选择联合查询的联合次序。
(3)在子查询中慎重使用IN或者NOT IN语句,使用where (NOT) exists的效果要好的多。
(4)慎重使用视图的联合查询,尤其是比较复杂的视图之间的联合查询。一般对视图的查询最好都分解为对数据表的直接查询效果要好一些。
(5)可以在参数文件中设置SHARED_POOL_RESERVED_SIZE参数,这个参数在SGA共享池中保留一个连续的内存空间,连续的内存空间有益于存放大的SQL程序包。
(6)Oracle公司提供的DBMS_SHARED_POOL程序可以帮助程序员将某些经常使用的存储过程“钉”在SQL区中而不被换出内存,程序员对于经常使用并且占用内存很多的存储过程“钉”到内存中有利于提高最终用户的响应时间。