这是我前几天整理的一篇 数据库优化的文章,贴出来与大家共享。
据统计,以数据库为中心的应用程序80%的性能问题是低效的SQL语句引起的,所以SQL的性能优化显得十分重要。另一方面,Oracle数据库应用系统运行阶段,DBA(数据库管理员)对系统参数配置不合理导致数据库运行性能低下,再者数据库物理结构的不合理也是导致性能低下的原因,本文主要从这些方面展开对oracle数据库应用性能的讨论。[2]
1. SQL优化
1.1 索引提升性能
Oracle采用 2种访问表中记录的方式:全表扫描和通过
ROWID访问表。全表扫描就是顺序的访问表中每条记录,该扫描方式耗费的时间和系统资源均较高;通过ROWID访问表,ROWID包含了表中记录的物理位置信息,Oracle采用索引(Index)实现了数据和存放数据的物理位置(ROWID)之间的联系,索引提供了快速访问ROWID的方法。
通过在许多情况下,针对数据表中的某个字段创建索引可以很快查询到所需的数据,一般来说应遵循以下基本原则:
(1)该字段是否为关键字,主键和外键须添加索引。
(2)为经常出现在关键字ORDER BY、GROUP BY、DISTINCT后面的字段,建立索引。
(3)对经常与表进行连接的表的连接字段建立索引。
索引虽有助于提高性能,但并不是索引越多越好,过多的索引会导致系统低效,用户在表中每加进一个索引,维护索引集合就要做相应的更新工作,加重相应的更新代价。[3]
1.2 SQL语句优化
SQL语句优化的实质就是在结果正确的前提下,用优化器可以识别的语句,充分利用索引来减少表扫描的I/O次数,尽量避免表搜索的发生。优化的目的就是将性能低下的SQL语句转换成目的相同的、性能优异的SQL语句,使数据查找的路径最简化,并尽量保持处理器时间和I/O时间的平衡。通常分为以下几个步骤:1)查找有问题的SQL语句。优化有问题的sql语句能显著提高数据库性能。寻找的方法有:搜集统计数据,oracle中可以通过DBMSSTATS包或ANALYZE命令,前者
可用于搜集有关链接数据行的统计数据,簇的数据情况只能使用ANALYEZ命令获得,其相关语法为ANALYEZE CLUSTERCluste_name ComputerSTATISTICS,对于其它情况可以使用DBMS_SATS包,语法为:execDBMS_SATS.gather_table_stats(‘owname’,’tablename’,’partnmae’);利用SQLTrace工具分析SQL语句。通过命令ALTER SESSION SET SQL_TRACE=TRUE会话激活SQL_TRACE,oracle就会在udump管理区创建跟踪文件,从而可以了解如解析、执行和返回数据的次数、CPU时间和执行时间、物理读和逻辑读操作次数、库缓冲区命中率等参数;通过oracleEnterpriseManager Console、Oracle Diagnostics Pack等图形性能工具能够很快地获取到数据库缓冲区命中率、CPU利用率、运行时内存等重要的数据库性能指标信息,并将它们以GUI表格形式和曲线图形式显示出来;2)建立合适的SQL语句。参照原则如下:建立“适当”的索引,使用索引的根本目的就是为了提高查询效率,但索引也不是越多越好,使用索引时应遵循相应的原则。此外,为了降低I/O竞争,索引不应与用户表空间建在同一磁盘上;避免使用耗费资源的操作如DSJTNITC、UNION、GROUP BY、ORDERBY等关键字,因为他们会启动SQL引擎执行耗费资源的排序功能。[4]
2. 数据库应用系统参数优化
2.1 调整服务器内存分配
服务器内存分配是在应用系统运行过程中优化设置的。DBA根据数据库的运行状况不仅可以调整数据库系统全局区(SGA区)的数据缓冲区、日志缓冲区和共享池的大小,而且还可以调整程序全局区(PGA区)的大小。
系统全局区(SGA)是一个分配给ORACLE包含ORACLE数据库实例控制信息的内存段。SGA的大小对系统性能的影响极大,其缺省参数设置只适用于配置很低的计算机,对现有较大资源的系统,这些参数若不作调整,会对系统资源造成巨大浪费。例如:现有服务器系统内存为256MB时,SGA的大小以160MB左右为宜。初始化参数文件中的一些参数对SGA的大小有决定性的影响。参数DB-BLOCK-BUFFERS(SGA中存储区高速缓存的缓冲区数目),参数SHARED-POO-L-SIZE(分配给共享SQL区的字节数),是SGA大小的主要影响者。DB-BLOCK-BUFFERS参数是SGA大小和数据库性能的最重要的决定因素。该值较高,可以提高系统的命中率,减少IPO。每个缓冲区的大小等于参数DB-BLOCK-SIZE的大小。ORACLE数据库块以字节表示大小。ORACLESGA区共享池部分由库高速缓存、字典高速缓存及其他一些用户和服务器会话信息组成,共享池是最大的消耗成分。调整SGA区各个结构的大小,可以极大地提高系统的性能[2]:
(1)调整LibraryCache
库高速缓存(Library Cache)中包含私用和共享SQL区和PLPSQL区。调整SGA的重要问题是确保库高速缓存足够大,以使ORACLE能在共享池中保持分析和执行语句,提高语句分析和执行效率,降低资源消耗。通过比较LibraryCache的命中率来决定它的大小。
(2)调整数据字典高速缓存(DictionaryCache)
数据字典高速缓存包括了有关数据库的结构、用户、实体信息等。数据字典的命中率对系统有很大的影响。
(3)调整数据库缓冲区高速缓存
ORACLE在运行期间向数据库高速缓存读写数据,高速缓存命中表示信息已在内存中,高速缓存失败意味着ORACLE必需进行磁盘IPO。保持高速缓存失败率最小的关键是确保高速缓存的大小。初始化参数DB-BLOCK-BUFFERS控制数据库缓冲区高速缓存的大小。[9]
2.2 调整磁盘IPO
磁盘IPO是系统性能的瓶颈,解决好磁盘IPO,可明显提高性能。通过查询VÃFILESTAT可以知道每个物理文件的使用频率(phyrds表示每个数据文件读的次数,phywrts表示每个数据文件写的次数)[10]
SQL>SELECTname,phyrds,phywrts FROM VÃdatafile df,VÃfilestat fs WHEREdf.file#=fs.file#;
对于使用频率较高的物理文件,可以采用以下策略:
(1)将组成同一个表空间的数据文件平均分配在尽可能多的磁盘上,做到磁盘之间IPO负载均衡;
(2)为表和索引建立不同的表空间;
(3)将数据文件与重做日志文件分离在不同的磁盘上;
(4)减少不经ORACLESERVER的磁盘IPO。
2.3 调整资源竞争
当多个进程对相同资源发出申请时,产生竞争。
(1)修改process参数
该参数定义可以同时连接到ORACLE数据库的最大进程数,缺省值为50。注意,ORACLE的后台进程也包括在此数目中,建议将该值改为200。
(2)减少调度进程的竞争
减少调度进程的竞争,通过查询VÃdispatcher表来判定调度进程的竞争SQL>SELECT network,sum(busy)Psum(busy)+sum(idle)
FROM VÃdispatcher GROUP BYnetwork;
如果某种协议忙的比率超过50%,应增加MTS-DISPATCHERS的值。
(3)减少多线程服务进程竞争
首先查询VÃSYSSTAT表判定是否发生多线程服务进程竞争:
SQL>SELECT DECODE(total q,0,.No request.,
waitPtotal q+.hunderths of seconds.)
FROM VÃsysstat WHERE type=.common.;
如果共享服务进程数量已达到初始化参数文件中MTS-MAX-SERVERS指定的最大值,但应用运行时,平均请求等待时间仍持续增长,那么,应加大MTS-MAX-SERVERS的值。
(4)减少重做日志缓冲区竞争
通过查询VÃSYSSTAT表判定redo log文件缓冲区是否足够。
SQL>SELECTname,value
FROM VÃsysstat
WHERE name=.redo log space request.;
此处value的值应接近于0,否则,应增大初始化参数文件的LOG-BUFFEQS的值[11]。
(5)减少回退段竞争
回退段对性能也有影响,根据事务大小情况来分配合适的回退段。
首先判定回退段的数量能否满足系统运行的需要:
查询VÃWAITSTAT表与VÃSYSSTAT表
SQL<SELECTclass,count FROM VÃwaitstat
WHERE class IN(.systemundo header.,systemundo
block.,.undo header.,.undo block.);
SQL>SELECTsum(value) FROM VÃsysstat WHERE nameIN(.db block
gets.,.consistentgets.);如果任何一个classPsum(value)
>10%,那么考虑增加回退段。
(6)减少Free List竞争
当多个进程同时向一个表中插入数据时,产生Free List竞争。
3. 优化数据库物理结构
3.1 优化设置控制文件的个数,位置及其备份
建议CONTROL_ FILE初始化参数中指定多个文件应大于2,并将控制文件镜像到不同位置,并要把这些控制文件备份到安全的磁盘中。
3.2 优化设计表空间,数据文件的大小及位置
3.2.1 设计表空间
尽量把同一时间对磁盘的读写操作分散开,如对一个表中数据进行更新时,数据库将同时去读该表中的数据和该表上的索引信息,如果把表的数据信息和索引信息都放在同一个数据文件中,则数据库的速度将会变慢。最好是把数据信息和索引信息分别放在不同磁盘的两个数据文件中,此时数据库对磁盘的读写操作将分散在两个磁盘上,速度将得到显著提高。因此在设计数据库的表空间和数据文件时,首先给表和表的索引分别创建两个表空间(存放用户数据的数据表空间和存放表索引的索引表空间)。另外,还根据该系统的数据量的大小及系统中的数据的性质不同,再考虑创建几个数据表空间或者给数据表空间添加几个数据文件。
3.2.2 设计数据文件的大小
把记录大小相当的表放在同一个表空间中,这时一个表空间的存储参数设置,可以保证表中的记录都放在一个范围中,避免了一条记录跨范围存放,可以明显数据库的性能。
3.2.3 设计数据文件的位置
为了避免磁盘的I/O操作冲突,应把数据文件创建在不同位置。
3.3 优化设计重演日志文件
3.3.1 重演日志文件的大小
由于数据库在利用重演日志文件时是循环使用它们的,而且当LGWR进程在两个日志文件切换时,将自动产生一个检测点,所以重演日志文件的大小会直接影响到检测点出现的频率。而由于在数据库检测点时,对用户而言,数据库的速度会受影响,所以检测点的出现频率大,或者检测点正好出现在数据库处理数据高峰期,将会极大影响数据库的性能。因此,重演日志文件的大小设计,应考虑检测点出现的频率以及检测点应避开数据库处理数据的高峰期。
3.3.2 重演日志文件组的个数
在ARCHIVELOG模式下时,适当增加重演日志文件组的个数,可以降低数据库存档日志文件的频率。
3.3.3 重演日志文件的存档
应把重演日志文件的存档之处设置在磁盘读写更快的物理设备上。这样可以减少日志文件的存档时间。[5]
4. 数据库集群
集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理.数据库集群系统是由多个共享一个数据库的有独立操作系统的服务器组成[6]
Oracle 10g RAC是一种基于网格服务的数据库集群系统架构,它具有每一层计算堆栈上的虚拟化、根据策略和动态需求来分配工作和资源、集中资源以提高利用率、能自我调整和修补、可统一管理和供应的特点[7].
每一层计算堆栈上的虚拟化.Oracle 10g RAC通过虚拟化将网格中的每一个物理和逻辑实体都抽象为一项服务.虚拟化使得网格中的存储器、处理器、数据库服务器等组件紧密地集成在一起,并且使得每一个组件在不损害整体的系统性能的前提下,根据不断变化的环境快速地作出反应,快速适应并屏蔽组件故障.此外,RAC是动态地创建一个连接,将来自某个特定应用程序的请求分配给数据库集群中的一个服务器节点处理.
根据策略和动态需求来分配工作和资源.RAC通过网格服务中介自动且动态地将网格的某个元素的资源需求和另一个元素的资源可用性连接在一起,动态地分配需要处理的服务器请求、需要访问和使用的数据以及需要执行的计算,使资源得到有效地利用.随着环境的变化,它还能调整这种关联.根据制定的策略,RAC进一步优化了集群中资源请求者与资源提供者之间的关联,使得预期的高峰需求等问题得到了有效处理.
集中资源以提高利用率.RAC通过网格服务动态地将服务消费者与服务提供者连接在一起,并通过共享的磁盘存储阵列及构建数据库集群系统将资源合并和集中,实现了更高的资源利用率.
自我调整和修补.RAC具有自我调整和修补的自适应功能,使得系统接管了许多过去必须由管理员才能处理的工作,并且系统处理得比以前更好.这样,不仅提高了系统效率,而且使得管理员有更多的时间和精力去做更重要的工作.
统一管理和供应.RAC通过将集群系统看作单个逻辑实体,使用自我管理功能和数据库控制来统一、监控和管理网格中的每一个元素.通过图形化的Web管理界面,管理员可以主动监视数据库,并很快得到任何系统瓶颈问题或者任何不可用组件所引起的警报和建议.[8]
5. 结语
数据库应用系统的优化是一个系统工程,涉及的方面很多。程序员和数据库管理员需要认真分析Oracle在运行过程当中出现的各种问题,以保证Oracle数据库应用系统运行的高效率。
遗憾的是,对像Oracle这样的数据库进行调整和性能调节并不是一件容易的事。Oracle带有几种监控和调试工具,功能强大,但精通掌握十分困难。这就需要开发一个数据库应用系统优化软件,对程序员和有经验的数据库管理员都适用。程序员可以把它用在基于Oracle的应用系统的开发过程和测试过程中,而数据库管理员会觉得有益于调整已开发出来的应用系统,因为数据库随时间不断变化,数据库管理员们能使用该软件即时查看数据库内部的运行情况,从而使数据库应用系统的性能得到提高。相信不久,人们将开发出一个适合程序员和数据库管理员使用的数据库应用系统优化软件。