Oracle 数据库性能优化分析与配置
来源:电脑知识与技术杂志 更新时间:2013-10-09
 
作为数据库管理员,如何保持和优化数据库服务器的性能,是一个必须解决的问题。该文介绍了影响Oracle 数据库性能的相关因素,从存储管理、内存优化以及日常维护等方面,给出了实现Oracle 数据库性能优化的相关配置。
  Oracle数据库是目前主流的商用数据库之一,随着硬件价格的下降,以及Oracle数据库强大的数据管理能力和良好的平台支持性,被越来越多的用户使用。因此,如何使用Oracle数据库实现一个高效的数据管理平台,被广泛关注。下面从Oracle数据库实例的存储管理、内存参数设置和日常维护等方面,分析影响数据库性能的原因,从而通过合理的配置,实现一个高效的数据管理平台。
  1、存储管理
  系统的I/O性能是Oracle数据库系统的性能瓶颈之一,选择高速可靠的存储设备,是解决数据库性能问题的重要手段,在已有存储设备的基础上,如何合理的配置,也是提高Oracle数据库性能的有效手段。
  1.1 使用磁盘阵列
  在数据库服务器上,使用冗余独立/廉价磁盘阵列(Redundant Array of Independent/Inexpensive Disks,RAID)配置磁盘几乎已经成为一种规范,使用磁盘阵列可以改进性能和可用性。但是,选择单块磁盘时,应该根据数据库需要存储的数据量的大小来选择磁盘容量,过大的容量会带来不适当的冗余和较差的性能。同时,要根据数据库的特点,选择合适的RAID级别。RAID 5对于有大量读操作的应用程序可以获得最大的性能,这是一种低成本的解决方案,但是对于大量写操作的Oracle应用程序,效率并不高。RAID 10是先镜像,然后再对其进行分段,这是最常见的Oracle OLTP产品的RAID级别。它通过将RAID 0的磁盘I/O分段优势融入到RAID 1带来的镜像,结合了这个两个RAID级别的优点。在高读/写量的环境(如OLAP)中,由于对数据的小规模访问会很频繁,建议使用RAID 10。在硬件条件允许的情况下,还可以使用RAID 10或者RAID 5的改进方案。对于使用了磁盘阵列,不再需要把磁盘阵列上的一个逻辑设备分割成操作系统的多个盘区,因为这样做会增加必须管理的数据文件位置的数量,从而使得系统I/O性能下降。
  1.2 关键数据文件分开存储
  为了更有效地在文件系统上操作Oracle数据库,应该把关键的数据文件分布到可用的文件系统中。以下元素关联的文件应该尽可能分离:SYSTEM表空间、TEMPORARY表空间、UNDO表空间、联机重做日志文件(最好放在最快的磁盘上)、操作系统盘、放在ORACLE_HOME目录下的关键ORACLE文件、经常被访问的表的数据文件、经常被访问的索引的数据文件、归档区域等。同时,分开存储数据和索引文件。把关键的Oracle数据文件分开放置,这样可以避免磁盘争用成为一个“瓶颈”。通过把经常连接的几个表的表和索引分开放置,保证即使最糟糕的表连接也不会导致磁盘争用。
  1.3 使用本地管理的表空间
  在Oracle 8i之前,所有表空间的段的盘区信息都通过Oracle数据字典进行维护,这样,发生在数据库的段上并关系到盘区分配的操作,例如扩展或截取一个表,将会导致对数据字典的操作。如果有很多拥有大量盘区的表被操作时,维护数据字典将会成为这些操作的瓶颈。Oracle 8i推出了新的盘区管理方式,叫本地管理的盘区,通过本地管理的盘区,盘区管理操作被重新分配到数据文件头中的位图块中,数据库的每个表空间都只包含自己的盘区信息,可以使用快速散列进程访问该信息,而不是使用较慢的基于表的查询访问,因而使用本地管理的表空间,可以提高性能。可以创建本地管理的表空间,也可以把数据字典管理的表空间迁移到本地管理的表空间。
  1.4 使用分区来避免磁盘争用
  分区技术是基于海量数据的数据库系统(比如数据仓库或者OLAP系统)中最重要的一个技术,很难想象,在一个存储着上TB或者几十TB的数据库中,数据表不使用分区的情况。分区可能是提高与大型表有关的性能的最佳方法。通过访问一个表或索引的较小片段,而不是访问整个表或索引,分区可以很好地提高效率。这个策略在一个或多个用户访问同一个表的多个部分时特别有效。如果一个表的分区(片段)位于不同的设备上,吞吐量就会大大增加,分区还可以被独立地备份和恢复,这样可以减少备份期间可能出现的磁盘I/O问题。仅当分区被正确实现后,才能体现Oracle性能提高的良好优点。设计良好的分区,在数据操作中,可以很好的实现分区规避,同时对索引进行分区,并使用并行选项,可以使分区功能更强大。为了最小化对一个大表的磁盘I/O,应该把表分割在多个分区上,这些分区应该放置在不同的物理磁盘上。
  1.5 使用自动存储管理(Automatic Storage Management,ASM)
  在Oracle Database 10g Release 2中,使用自动存储管理极大地简化了数据库的存储管理和配置。ASM提供了内置于Oracle数据库内核中的文件系统和卷管理器功能,提供了跨越所有服务器和存储平台的简单存储管理界面。提供了管理动态数据库环境的灵活性,并且可以有效地提高效率。
  ASM主要有以下优点:
  1)将I/O均匀地分布到所有可用磁盘驱动器以防止产生热点,并且最大化性能;
  2)不再需要过多地进行配置工作,并且最大化推动数据库合并的利用存储资源;
  3)内在地支持大文件;
  4)在增量增加或删除存储容量后执行自动联机重分配;
  5)维护数据的冗余副本以提高可用性,或者利用第三方的RAID功能。
  Oracle数据库可以包含ASM文件和非ASM文件,任何新的文件都可以创建为ASM文件,已有的文件也可以迁移到ASM。ASM降低了Oracle数据库的成本和复杂性,并且不会影响到性能或可用性。构建ASM的主要用途是解决数据库的配置和布局以及IT角色之间的通信。有资料表明,在同样的硬件条件下,使用ASM比使用操作系统的文件系统的I/O要快26%左右。
  总之,通过以上这些配置要么是提高磁盘I/O性能,要么就是减少I/O争用,以此来提高数据库性能。
  2、内存优化
  Oracle实例的内存使用对性能起着至关重要的作用。如果未按最佳方式为各种结构分配内存量,性能将急转直下。分配的内存量不能过少,也不能过多。在较早的数据库版本中,DBA只有掌握大量的知识,花费大量的时间才能调整内存的使用,但是在11g版本中,内存调整大多可以自动完成。
  Oracle实例中的内存使用分为两类:程序全局区域(Program Global Area,PGA)和系统全局区域(System Global Area,SGA),前者专门供每个会话使用,后者由所有Oracle进程共享。从9i版本开始,PGA的管理实现了自动化,从10g版本开始,SGA的管理实现了自动化,11g版本可同时自动管理PGA和SGA。
  2.1 PGA 内存管理
  针对Oracle实例的用户会话由连接到服务器进程的用户进程组成。用户进程生成SQL语句,并将它们发送到服务器进程供执行,这就是客户端与服务器的分工。与服务器进程关联在一起的是非共享内存块:PAG。在执行SQL语句时,服务器进程使用PGA来存储会话特有的数据,包括:临时表、排序表、归并位图、变量、调用堆栈。PGA中的某些数据必须使用内存。例如,如果会话的调用堆栈需要内存,那么,相应的内存必须可供使用。而对于其他存储结构,例如临时表存储,使用PGA的效果是不错的,但PGA并不是必需的,因为可以将数据写到基于磁盘的存储结构中,但是这会对性能产生负面影响。Oracle强烈建议使用自动管理PGA内存。实现自动PGA内存管理,需要设置PGA内存分配总量(所有会话需要量之和)的目标,此后,Oracle实例将根据需要,从总量中为会话分配内存,在某个会话执行完语句后,此会话使用的PGA可以分配给另一会话。在任何时刻,只有某些已经连接上的会话需要任何可转让的PGA内存,即使会话处于闲置状态,也都需要一定量的PGA内存来保留当前会话的状态,但总体看来,这会留下足够的空间使正在实际运行语句的会话获得需要的内存。
  使用两个实例参数来启用PGA 内存的自动管理:WORKAREA_SIZE_POLICY,PGA_AGGREGAT_TARGET,WORKAREA_SIZE_POLICY的默认值是AUTO,就是自动将PGA分配给用户,同时力求将PGA分配的总量保持在PGA_AGGREGAT_TARGET范围以内。
  2.2 SGA 内存管理
  SGA包含多个内存结构,这些结构的大小可以以独立方式调整,主要有:共享池、数据库高速缓存区、大池  、流池、Java池、日志缓冲区。分配给大池、Java池和流池的内存与转让无关,原因是需要这样的内存,或者相应的内容不可转让。如果这些结构不够大,将发生错误;如果这些结构过大,也不会提高性能。分配给共享池、数据库高速缓存区和日志缓存区的内存是可以转让的;如果达不到最优大小,不会发生错误,但性能会因此下降。共享池是一个例外:如果在较长时间内达不到最优大小,将会发生错误。
  Oracle公司同样建议对SGA内存进行自动管理。设置SGA的总大小,实例依据总量将内存分配给各个结构,确保不存在因SGA组件不够大带来错误,且分配大于最小限度的内存使SGA组件可以最佳状态执行。根据需要调整组件的大小,这样,如果组件需要更多内存,可以从具有多余空间的组件那里获取内存。要启用SGA自动管理,则保留上述内存结构参数的默认值,并设置一个参数,来启用自动共享内存管理:SGA_TARGET,在使用自动共享内存管理时,实例将监视各个SGA组件的内存需求,并根据需要将内存分配给组件,如有必要,会减少内存容量,以便将内存分配总量控制在目标范围内。包含在目标范围的还有日志缓冲区,其大小使用LOG_BUFFER参数进行设置。LOG_BUFFER的默认大小可能是正确的,可将此参数设置得比默认值更大,但这往往会导致性能下降,如果将其设置得低于默认值,将忽略相应设置。
  2.3 Automatic Memory Management
  使用Automatic Memory Management机制时,通过设置MEMORY_TARGET这个参数,就可以让Oracle实例在总体上管理服务器内存的使用。这允许Oracle根据需要,在PGA和SGA之间转换内存,从而将自动PGA管理和自动SGA管理又向前推进了一步。自动内存管理会带来巨大的性能优势。在实例运行过程中,无法根据活动模式的更改,在SGA和PGA之间手工转换内存,而且很多系统也无法同时为二者分配足够的内存,来满足它们的峰值需求;自动内存管理能够根据需要,在SGA和PGA之间转换内存,以便在内存总量允许的范围内优化性能。必须由DBA和系统管理员共同确定总量大小,如果DBA设置的上限过大,以至于操作系统必须将SGA和PGA分页写入交换设备,这将会失去意义;系统管理员将建议适当的最大值。
  MEMORY_MAX_TARGET参数限制了MEMORY_TARGET参数的最大值不能超过。因此启用自动内存管理,只要设置一个参数MEMORY_TARGET,而不必设置上面列出的其他参数。
  2.4 使用内存顾问程序
  Oracle实例收集大量有关活动和性能的信息。这些统计信息收集到内存中,并由MMON(Manageability Monitor)后台进程定期转储到自动工作负荷仓库(Automatic Workload Repository,AWR),这些统计信息供内存顾问程序使用。内存顾问程序是计算更改SGA和PGA内存结构大小的效果的工具。AWR工具使用顾问程序制定有关内存分配的决策,DBA可以通过各种视图或者Enterprise Management Database Control看到他们。通过查询V$pga_target_advice、V$sga_target_advice和V$memory_target_advice,可以分别得到最佳的PGA、SGA和内存分配值。如果使用自动内存管理,仅需要查询最后一个视图,来确定Oracle实例总内存的最佳分配值。同样,可以通过Enterprise Management Database Control,使用顾问程序来收集有关内存分配的建议,通过打开Memory Advisors链接,可以分别查找SGA、PGA和Memory的当前设置大小和建议的最佳大小。
  3、日常运行和维护
  在数据库的长期运行过程中,随着数据量的增加,以及数据物理存储的变化,数据库的性能会有所下降,所以,对数据库进行相关的日常维护,也是提高数据库性能的重要手段。
  3.1 归档旧的数据
  遵循“二八”原则,数据库中有很多数据很少被访问到,所以应该对于这些“历史”数据,进行相应的归档操作。如果是已经使用了分区的表,可以通过分区合并和拆分,进行数据归档。以此来降低查询数据时的磁盘I/O量,减少DML操作时的锁冲突,提高数据库性能。
  3.2 管理无效对象和无用对象
  决定性能的另一关键因素是数据库中各种对象的状态,如果PL/SQL对象是无效的(INVALID),则会对性能产生负面影响,也可能导致错误;如果无法使用索引,那么SQL语句的执行速度可能大大降低,并更密集地使用资源。应该识别、了解和修复所有无效对象和不可用的对象。
  1)无效对象
  存储的PL/SQL是数据字典中编译为PL/SQL对象并在其中保持的代码,可以是过程、函数、触发器、程序包或对象类型。这些对象大多数会引用数据对象(例如表)。在编译对象时,编译器将检查器引用的数据对象,以便确认代码的定义正确。如果编译时发现引用的数据对象不存在,会将该对象标记为无效;但是对象可能在创建一段时间之后变得无效。DBA_OBJECTS视图包含STATUS列,该列标记对象的状态是有效还是无效。如果有相关的无效对象,应该进行删除或者修复。
  2)无用的索引
  一个索引由若干按照顺序排列的索引键值组成,其中每个索引键值都具有相关联的rowid,rowid是索引键引用的行的物理位置的指针。如果某个表的rowid发生变化,那么索引就会被标记为无用。索引变得无用的原因有许多种,其中最常见的是使用Alter table……move命令移动了指定的表,会改变所有行的物理位置,因此索引被指向错误的位置,对于分区表的分区调整,也同样会产生无用索引。随着时间的推移,执行了许多影响行键值的删除和更新操作,索引往往会变得无用。Oracle会发现这个错误,从而不允许使用该索引。
  在Oracle 11g版本中,如果某条SQL语句试图使用无用的索引,那么查询会重新使用不需要该索引的执行计划,SQL语句的执行总会成功,不过查询的性能会显著降低。这种方式由实例参数SKIP_UNUSABLE_INDEXES控制,它的默认值是TRUE。如果希望在查询中使用到无用索引时返回错误消息,那么可以执行Alter System Set SKIP_UNUSABLE_INDEXES=FALSE。通过查询DBA_INDEXES视图,运行Select owner, index_name from dba_indexes where status=’UNUSABLE’,可以查找变得无用的索引,并使用Alter Index …… Rebuild命令重新创建该索引。重建索引是数据库正常维护工作的一部分。
  3.3 消除数据碎片
  碎片会阻碍数据库的空间管理,但总的说来,一个段中的盘区量的多少总是会影响数据库性能。拥有很多跨多个数据文件的不连续盘区的位图索引就是一个大的性能问题。可以使用正确的盘区大小以消除碎片,对于已经有碎片的数据表,可以创建一个新表空间并把数据移到其中。
  3.4 增加日志文件的大小
  增加日志文件的大小和LOG_CHECKPOINT_INTERVAL以提高速度,如果想让大量的INSERT、UPDATE和DELETE操作速度更快,可以增加日志文件大小,并确保这些文件在最快的磁盘上。Oracle依赖于联机重做日志文件来记录事务处理。每次数据库中发生一次事务处理,联机重做日志文件中就会增加一个条目。如果增大分配给日志的空间,就可以提高性能,没有提交的事务同样会生成日志条目,因为它们生成撤销记录,这些撤销记录也写入到重做日志。增加日志文件的大小,从而增加处理大型IN?SERTS、DELETES和UPDATES(DMLs)操作的规模。
  3.5 配置UNDO 表空间
  回滚段保存了在一次更新和删除期间内的数据快照,如果初始化参数UNDO_MANAGEMENT=MANUAL,那么就可以像Oracle前面的版本一样使用回滚段。如果初始化参数UNDO_MANAGEMENT=AUTO,就使用撤销表空间管理。当事务回滚时,就要用到数据快照,如果把数据库设置为使用回滚段,要为各个回滚段保留多个表空间,这样用户就不会在同一个表空间中出现争用现象。在Oracle 9i中,提出了一个管理Rollback或UNDO数据的新办法,就是使用UNDO表空间,大大简化了对事务的管理。在回滚段中,撤销块会根据需要被新的事务重写,因而要保证有足够大的回滚段可用于事务。从而避免执行大的事务时发生快照太旧的错误,并且保证有足够的回滚段来维护数据库中的常规活动,从而最小化回滚段的争用。为了利用自动撤销管理,可以在数据库中创建UNDO类型的表空间。并在初始化文件中指定3个新的参数:UNDO_MANAGEMENT=AUTO, UNDO_TABLESPACE=UN?DOTBS1, UNDO_RETENTION= 时间值,UNDO_RETENTION初始化参数用来指定撤销数据被提交之后保留在表空间中的数据值(秒),这是使用撤销表空间的真正优点,因为不同于传统的回滚段,数据库至少会尝试为长期运行的查询维护较早版本的数据。如果将UNDO_MANAGEMENT设置为AUTO,即使用自动撤销管理,就要将UNDO_TABLESPACE配置一个具体的表空间,如果没有配置,则使用SYSTEM表空间,这将会影响数据库性能。
  通过V$UNDOSTAT视图可以监控实例中当前事务使用UNDO表空间的情况,视图中的每行表示在过去24小时里每隔10分钟UNDO表空间的使用情况、事务量和查询长度等信息的统计快照,通过分析这些信息可以对UNDO表空间进行重新配置。
  4、结束语
  有关Oracle数据库性能优化的方法还有很多,例如配置RAC、实现Data Guard以及SQL查询优化等,相关的论文有很多,这里不再讨论。
  总之,在硬件设备既定的情况下,通过上述的相关配置,能够进一步的提高和优化Oracle数据库的性能,实现一个功能强大的数据库管理平台。