|
知识路径: > 测试技术的分类 > 应用负载压力测试 > 负载压力测试实施 >
|
考试要求:掌握
相关知识点:70个
|
|
|
|
|
|
|
并发用户数是负载压力测试的主要指标,体现了系统能够承受的并发性能。
|
|
|
测试重点得到两类并发用户数指标,一类是系统最佳性能的并发用户数,另一类是系统能够承受的最大并发用户数,这两类指标在某种情况下有可能重叠。
|
|
|
|
该指标描述交易执行的快慢程度,这是用户最直接感受到的系统性能,也是故障定位迫切需要解决的问题。
|
|
|
|
指每秒钟能够成功执行的交易数,描述系统能够提供的“产量”,用户可以以此来评估系统的性能价格比。
|
|
|
|
指每秒通过的字节数,以及通过的总字节数。此指标在很大程度上影响系统交易的响应时间,形成响应时间的“拐点”。
|
|
|
|
|
|
资源占用主要涉及服务器操作系统资源占用、数据库资源占用、中间件资源占用等内容,下面分别论述。
|
|
|
|
通过《负载压力测试指标》章节的讨论,可以将服务器操作系统资源占用监控指标概括为以下几个方面:
|
|
|
|
|
|
|
|
|
|
|
. Memory:内存使用情况可能是系统性能中最重要的因素。如果系统“页交换”频繁,说明内存不足。“页交换”是使用称为“页面”的单位,将固定大小的代码和数据块从RAM移动到磁盘的过程,其目的是为了释放内存空间。尽管某些页交换使Windows 2000能够使用比实际更多的内存,也是可以接受的,但频繁的页交换将降低系统性能。减少页交换将显著提高系统响应速度。要监视内存不足的状况,请从以下的对象计数器开始。
|
|
|
①Available Mbytes:可用物理内存数。如果Available Mbytes的值很小(4MB或更小),则说明计算机上总的内存可能不足,或某程序没有释放内存。
|
|
|
②page/sec:表明由于硬件页面错误而从磁盘取出的页面数,或由于页面错误而写入磁盘以释放内存空间的页面数。一般如果pages/sec持续高于几百,那么应该进一步研究页交换活动。有可能需要增加内存,以减少换页的需求(你可以把这个数字乘以4k就得到由此引起的硬盘数据流量)。pages/sec的值很大,不一定表明内存有问题,而可能是运行使用内存映射文件的程序所致。
|
|
|
③page read/sec:页的硬故障,page/sec的子集,为了解析对内存的引用,必须读取页文件的次数。阈值为>5,越低越好。大数值表示磁盘读而不是缓存读。
|
|
|
. 由于过多的页交换要使用大量的硬盘空间,因此有可能导致页交换内存不足与页交换的磁盘瓶颈混淆。因此,在研究内存不足不太明显的页交换的原因时,必须跟踪如下的磁盘使用情况计数器和内存计数器:
|
|
|
. Physical Disk\ %Disk Time。
|
|
|
. Physical Disk\ Avg.Disk Queue Length。例如,包括Page Reads/sec和% Disk Time及Avg.Disk Queue Length。如果页面读取操作速率很低,同时%Disk Time和Avg.Disk Queue Length的值很高,则可能有磁盘瓶颈。而如果队列长度增加的同时页面读取速率并未降低,则内存不足。要确定过多的页交换对磁盘活动的影响,请将Physical Disk\ Avg.Disk sec/Transfer和Memory\ pages/sec计数器的值增大数倍。如果这些计数器的计数结果超过了0.1,那么页交换将花费10%以上的磁盘访问时间。如果长时间发生这种情况,那么可能需要更多的内存。
|
|
|
. Page Faults/sec:每秒钟软性页面失效的数目(包括有些可以直接在内存中满足而有些需要从硬盘读取),而page/sec只表明数据不能在指定内存中立即使用。
|
|
|
. Cache Bytes:文件系统缓存(File System Cache),默认情况下为50%的可用物理内存。如果怀疑有内存泄露,请监视Memory\ Available Bytes和Memory\ Committed Bytes,以观察内存行为,并监视可能泄露内存进程Process\Private Bytes、Process\Working Set和Process\Handle Count。如果怀疑是内核模式进程导致了泄露,则还应该监视Memory\Pool Nonpaged Bytes、Memory\ Pool Nonpaged Allocs和Process(process_name)\ Pool Nonpaged Bytes。
|
|
|
. Pages per second:每秒钟检索的页数。该数字应少于每秒1页。
|
|
|
. Page Faults/sec:将进程产生的页故障与系统产生的相比较,以判断这个进程对系统页故障产生的影响。
|
|
|
. Work set:处理线程最近使用的内存页,反映了每一个进程使用的内存页的数量。如果服务器有足够的空闲内存,页就会被留在内存中,当自由内存少于一个特定的阈值时,页就会被清除出内存。
|
|
|
. Inetinfo:Private Bytes。此进程所分配的无法与其他进程共享的当前字节数量。如果系统性能随着时间而降低,则此计数器可以是内存泄漏的最佳指示器。
|
|
|
. Processor:监视“处理器”和“系统”对象计数器可以提供关于处理器使用的有价值的信息,帮助决定是否存在瓶颈。
|
|
|
. %Processor Time:被处理器消耗的处理器时间数量。如果该值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。
|
|
|
. %User Time:表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接、水平分割大表格等方法来降低该值。
|
|
|
. %Privileged Time:(CPU内核时间)是在特权模式下处理线程执行代码所花时间的百分比。如果该参数值和“Physical Disk”参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。另外设置“Tempdb in RAM”,减低“max async IO”,“max lazy writer I/O”等措施都会降低该值。此外,跟踪计算机的服务器工作队列当前长度的Server Work Queues\ Queue Length计数器会显示出处理器瓶颈。队列长度持续大于4,则表示可能出现处理器拥塞。此计数器是特定时间的值,而不是一段时间的平均值。
|
|
|
. %DPC Time:越低越好。在多处理器系统中,如果这个值大于50%并且“Processor:%Processor Time”非常高,加入一个网卡可能会提高性能,提供的网络已经不饱和。
|
|
|
. Context Switches/sec:如果决定要增加线程字节池的大小,应该同时监视实例化inetinfo和dllhost进程这两个计数器。增加线程数可能会增加上下文切换次数,这样性能不会上升,反而下降。如果多个实例的上下文切换值非常高,就应该减小线程字节池的大小。
|
|
|
. %Disk Time:指所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。如果只有%Disk Time比较大,而CPU和内存都比较适中,硬盘可能会是瓶颈。
|
|
|
. Avg.Disk Queue Length:指读取和写入请求(为所选磁盘在实例间隔中列队)的平均数。该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。注意,一个Raid Disk实际有多个磁盘。
|
|
|
. Average Disk Read/Write Queue Length:指读取(写入)请求(列队)的平均数。.Disk Reads(Writes)/s:物理磁盘上每秒钟磁盘读、写的次数。两者相加,应小于磁盘设备最大允许读取次数。
|
|
|
. Average Disksec/Read:指以秒计算的在此盘上读取数据的所需平均时间。.Average Disk sec/Transfer:指以秒计算的在此盘上写入数据的所需平均时间。.Bytes Total/sec:为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽进行比较。
|
|
|
|
通过《负载压力测试指标》章节的讨论,可以将数据库资源占用监控指标概括为:
|
|
|
|
|
|
. 共享内存中物理日志和逻辑日志的缓冲区的使用率。
|
|
|
. 磁盘的数据块使用情况以及被频繁读写的热点区域。
|
|
|
|
|
|
|
下面以SQL Server数据库性能计数器为例来分析。
|
|
|
. Access Methods:用于监视数据库逻辑页访问方法。
|
|
|
. Full Scans/sec:每秒钟不受限的完全扫描数。可以是基本表扫描或全索引扫描。如果这个计数器显示的值比1或2高,应该分析查询以确定是否确实需要全表扫描,以及SQL查询是否可以被优化。
|
|
|
. Page splits/sec:由于数据更新操作引起的每秒页分割的数量。
|
|
|
. Buffer Manager:监视SQL Server如何使用内存存储数据页、内部数据结构和过程高速缓存。计数器在SQL Server从磁盘读取数据库页和将数据库页写入磁盘时监视物理I/O。监视SQL Server所使用的内存和计数器,有助于确定是否由于缺少可用物理内存存储高速缓存中经常访问的数据,而导致瓶颈存在。如果是这样,SQL Server必须从磁盘检索数据,以及考虑是否可通过添加更多内存,或使更多内存可用于数据高速缓存或SQL Server内部结构来提高查询性能。
|
|
|
. Disk I/O:SQL Server从磁盘读取数据的频率。与其他操作相比,例如内存访问,物理I/O会耗费大量时间。尽可能减少物理I/O可以提高查询性能。
|
|
|
. Page Reads/sec:每秒钟发出的物理数据库页读取数。这一统计信息显示的是在所有数据库间的物理页读取总数。由于物理I/O的开销大,可以通过使用更大的数据高速缓存、智能索引、更高效的查询或者改变数据库设计等方法,使开销减到最小。
|
|
|
. Page Writes/sec:每秒执行的物理数据库写的页数。
|
|
|
. Buffer Cache Hit Ratio:在“缓冲池”(Buffer Cache/Buffer Pool)中没有被读过的页占整个缓冲池中所有页的比率。可在高速缓存中找到,而不需要从磁盘中读取的页的百分比。这一比率是高速缓存命中总数除以自SQL Server实例启动后对高速缓存的查找总数。经过很长时间后,这一比率的变化很小。由于从高速缓存中读数据比从磁盘中读数据的开销要小得多,一般希望这一数值高一些。通常,可以通过增加SQL Server可用的内存数量来提高高速缓存命中率。计数器值依应用程序而定,但比率最好为90%或更高。增加内存直到这一数值持续高于90%,表示90%以上的数据请求可以从数据缓冲区中获得所需数据。
|
|
|
. Lazy Writes/sec:惰性写进程每秒写的缓冲区的数量。其值最好为0。
|
|
|
. Cache Manager:对象提供计数器,用于监视SQL Server如何使用内存存储对象,如存储过程、特殊和准备好的Transact-SQL语句以及触发器。
|
|
|
. Cache Hit Ratio:Cache可以包括Log Cache, Buffer Cache以及Procedure Cache,是一个总体的比率,是高速缓存命中次数和查找次数的比率之和。其对查看SQL Server高速缓存对于系统性能提升如何有效,是一个非常好的计数器。如果这个值持续低于80%,就需要增加更多的内存。
|
|
|
. Latches:用于监视称为“闩锁”的内部SQL Server资源锁。监视闩锁以明确用户活动和资源使用情况,有助于查明性能瓶颈。
|
|
|
. Average Latch Wait Time(ms):一个SQL Server线程必须等待一个闩的平均时间,以毫秒为单位。如果这个值很高,系统可能正经历严重的竞争问题。
|
|
|
. Latch Waits/sec:在闩上每秒的等待数量。如果这个值很高,表明系统正经历严重的竞争问题。
|
|
|
. Locks:提供有关个别资源类型上的SQL Server锁的信息。锁加在SQL Server资源上(如在一个事务中进行的行读取或修改),以防止多个事务并发使用资源。例如,如果一个排它锁被一个事务加在某一表的某一行上,在这个锁被释放前,其他事务都不可以修改这一行。应尽可能少使用锁,可提高并发性,从而改善性能。可以同时监视Locks对象的多个实例,每个实例代表一个资源类型上的一个锁。
|
|
|
. Number of Deadlocks/sec:导致死锁的锁请求的数量。
|
|
|
. Average Wait Time(ms):线程等待某种类型的锁的平均等待时间。
|
|
|
. Lock Requests/sec:每秒钟某种类型的锁请求的数量。
|
|
|
. Memory manager:用于监视总体的服务器内存使用情况,以估计用户活动和资源使用,有助于查明性能瓶颈。监视SQL Server实例所使用的内存,有助于确定是否由于缺少可用物理内存存储高速缓存中经常访问的数据而导致瓶颈存在。如果是这样,SQL Server必须从磁盘检索数据,以及考虑是否可以通过添加更多内存,或使更多内存可用于数据高速缓存或SQL Server内部结构,来提高查询性能。
|
|
|
. Lock blocks:服务器上锁定块的数量,锁是加在页、行或者表这样的资源上。通常不希望看到此值增长。
|
|
|
. Total Server Memory:SQL Server服务器当前正在使用的动态内存总量。
|
|
|
|
|
|
|
|
|
|
. %File Cache Hits:是全部缓存请求中缓存命中次数所占的比例,反映了IIS的文件缓存设置的工作情况。对于一个由大部分静态网页组成的网站,该值应该保持在80%左右。File Cache Hits是文件缓存命中的具体值,而File CacheFlushes是自服务器启动之后文件缓存刷新次数,如果刷新得太慢,会浪费内存;如果刷新得太快,缓存中的对象会太频繁地丢弃生成,起不到缓存的作用。通过比较File Cache Hits和File Cache Flushes可得出缓存命中率与缓存清空率的比率。通过观察这两个值,可以得到一个适当的刷新值(参考IIS的ObjectTTL、MemCacheSize和MaxCacheFileSize设置)。
|
|
|
|
①Bytes Total/sec:显示Web服务器发送和接收的总字节数。低数值表明该IIS正在以较低的速度进行数据传输。
|
|
|
②Connection Refused:数值越低越好。高数值表明网络适配器或处理器存在瓶颈。
|
|
|
③Not Found Errors:显示由于被请求文件无法找到而导致的服务器无法回应的请求数(HTTP状态代码404)。
|
|
|
|
这里主要讨论故障分析内容以及优化调整设置内容,同时还与读者分享故障分析的经验与实例。
|
|
|
|
|
|
|
|
|
|
|
|
|
交易的响应时间如果很长,远远超过系统性能的需求,表示耗费CPU的数据库操作。例如排序,执行aggregate functions(例如sum、min、max、count)等较多,可考虑是否有索引以及索引建立得是否合理。尽量使用简单的表链接、水平分割大表格等方法来降低该值。
|
|
|
|
测试工具可以模拟不同的虚拟用户来单独访问Web服务器、应用服务器和数据库服务器,这样,就可以在Web端测出的响应时间减去以上各个分段测出的时间,就可以知道瓶颈在哪里并着手调优。
|
|
|
|
UNIX资源监控(NT操作系统同理)中指标内存页交换速率(Paging rate),如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈,也可能是内存访问命中率低。“Swap in rate”和“Swap out rate”也有类似的解释。
|
|
|
|
UNIX资源监控(NT操作系统同理)中指标CPU占用率(CPU utilization),如果该值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。合理使用的范围在60%~70%。
|
|
|
|
Tuxedo资源监控中指标队列中的字节数(Bytes on queue),队列长度应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。注意:一个Raid Disk实际有多个磁盘。
|
|
|
|
SQL Server资源监控中指标缓存点击率(Cache Hit Ratio),该值越高越好。如果持续低于80%,应考虑增加内存。注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。
|
|
|
|
针对上述故障分析的重点内容,需要做相应的优化调整,建议如下。
|
|
|
|
|
|
③考虑在其他体系上设计系统,例如增加前置机、设置并行服务器等。
|
|
|
|
①内存的优化包括操作系统、数据库、应用程序的内存优化;
|
|
|
|
|
|
⑤调整数据块缓冲区大小(用数据块的个数表示)是一个重要内容;
|
|
|
|
|
①磁盘读写进度对数据库系统是至关重要的,数据库对象在物理设备上的合理分布能改善性能。
|
|
|
|
③通过把日志和数据库对象分布在独立的设备上,可以提高系统的性能。
|
|
|
④把不同的数据库放在不同的硬盘上,可以提高读写速度。建议把数据库、回滚段、日志放在不同的设备上。
|
|
|
⑤把表放在一块硬盘上,把非簇的索引放在另一块硬盘上,保证物理读写更快。
|
|
|
|
|
②并行操作资源限制的参数(并发用户的数目、会话数)。
|
|
|
|
|
|
①可以通过数组接口来减少网络呼叫。不是一次提取一行,而是在单个往来往返中提取10行,这样做效率较高。
|
|
|
|
|
|
|
|
|
|
|
当在合理的加载下出现这些类型的问题时,则表示可能有基础性的设计问题,比如说:算法问题,低效的数据库应用程序交互作用等,这些都不是通过简单升级硬件以及调整系统配置就可以解决的问题,此时软件的故障定位和调优将占有更重要的地位。
|
|
|
|
目前Web开发者开始提供可定制的Web网站,例如,像搜索数据之类的任务,现在可以由服务器执行,而无需客户干预。然而,这些变革也导致了一个结果,这就是许多网站都在使用大量的未经优化的数据库调用,从而使得应用性能大打折扣。
|
|
|
|
|
|
|
|
优秀的网站设计都会关注这些问题。然而,与静态页面的速度相比,任何数据库调用都会显著地影响Web网站的响应速度,这主要是因为在发送页面之前必须单独地为每个访问网站的用户进行数据库调用。
|
|
|
这里提出的性能优化方案正是基于以下事实:访问静态HTML页面要比访问那些内容依赖于数据库调用的页面要快。它的基本思想是:在用户访问页面之前,预先从数据库提取信息,写入存储在服务器上的静态HTML页面。为了保证这些静态页面能够及时地反映不断变化的数据库数据,必须有一个调度程序管理静态页面的生成。
|
|
|
当然,这种方案并不能够适应所有的情形。例如,如果是从持续变化的大容量数据库提取少量信息,这种方案是不合适的。
|
|
|
每当该页面被调用时,脚本就会提取最后的更新时间并将它与当前时间比较。如果两个时间之间的差值大于预定的数值,更新脚本就会运行,否则,该ASP页面把余下的HTML代码发送给浏览器。
|
|
|
如果每次访问ASP页面的时候都要提供最新的信息,或者输出与用户输入密切相关,这种方法并不实用,但这种方法可以适应以固定的时间间隔更新信息的场合。
|
|
|
如果数据库内容由客户通过适当的ASP页面更新,要确保静态页面也能够自动反映数据的变化,我们可以在ASP页面中调用Update脚本。这样,每当数据库内容改变时,服务器上也有了最新的静态HTML页面。
|
|
|
另一种处理频繁变动数据的办法是借助Microsoft SQL Server 7.0或以上版本的Web助手向导(Web Assistant Wizard),这个向导能够利用Transact-SQL、存储过程等从SQL Server数据生成标准的HTML文件。
|
|
|
Web助手向导能够用来定期地生成HTML页面。正如前面概要介绍的方案,Web助手可以通过触发子更新HTML页面,比如在指定的时间执行更新或者在数据库数据变化时执行更新。
|
|
|
SQL Server使用名为sp_makewebtask的存储过程创建HTML页面,它的参数是目标HTML文件的名字和待执行存储过程的名字,查询的输出发送到HTML页面。另外,也可以选择使用可供结果数据插入的模板文件。
|
|
|
万一用户访问页面的时候正好在执行更新,我们可以利用锁或者其他类似的机制把页面延迟几秒钟。
|
|
|
我们对纯HTML加调度ASP代码和普通的ASP文件进行了性能测试。普通的ASP文件要查找5个不同的表为页面提取数据。为了和这两个文件相比较,对一个只访问单个表的ASP页面和一个纯HTML文件也进行了测试。测试结果如下表所示。
|
|
|
|
|
其中TTFB是指“Total Time to First Byte”, TTLB是指“Total Time to Last Byte”。
|
|
|
测试结果显示,访问单个表的ASP页面的处理时间是720.5ms,而纯HTML文件则为427ms。普通的ASP文件和纯HTML加调度ASP代码的输出时间相同,但它们的处理时间分别为3633.67ms和1590ms。也就是说,在这个测试环境下我们可以把处理速度提高43%。
|
|
|
如果我们要让页面每隔一定的访问次数进行更新,比如100次,那么这第100个用户就必须等待新的HTML页面生成。不过,这个代价或许不算太高,其他99个用户获得了好处。
|
|
|
静态页面方法并不能够适合所有类型的页面。例如,某些页面在进行任何处理之前必须要有用户输入。但是,这种方法可以成功地应用到那些不依赖用户输入却进行大量数据库调用的页面,而且这种情况下它将发挥出更大的效率。
|
|
|
在大多数情况下,动态页面的生成将在相当大的程度上提高网站的性能,而且无须在功能上有所折衷。虽然有许多大的网站采用了这个策略来改善性能,但也有许多网站完全由于进行大量没有必要的数据库调用,而表现出很差的性能。
|
|
|
|
数据库服务器性能问题主要表现在某些类型操作的响应时间过长、同一类型事务的并发处理能力差和锁冲突频繁发生等方面。应该说,这些问题是数据库服务器性能不佳的典型表现。由于造成上述情况的原因众多,需要分情况加以分析。
|
|
|
|
响应时间(Response Time, RT)是系统完成事务执行准备后所采集的时间戳和系统完成待执行事务后所采集的时间戳之间的时间间隔,是衡量特定类型应用事务性能的重要指标,标志了用户执行一项操作大致需要多长时间。响应时间过长意味着用户完成执行一项命令需要等待相当长的时间。实践表明,通常情况下用户能够接受的响应时间最大为200 ms。不仅如此,响应时间过长也是造成系统锁冲突严重的重要原因之一。
|
|
|
造成响应时间过长的原因非常复杂,通常可以从以下几个方面考虑。
|
|
|
|
|
|
|
|
数据库服务器负载过重不可避免地会造成响应时间过长。这标志着当前服务器系统的硬件条件不能满足实际用户对性能的需要。服务器负载过重主要表现在CPU使用率高、内存占用率大、I/O与页面交换频繁发生等方面。由于服务器系统本身一般都提供性能监控程序,定位服务器性能问题相对比较容易。解决这类问题的方法一般是升级服务器硬件,提高数据库服务器本身的处理能力。但是,通过升级服务器硬件获得的性能提升是很有限的,并且对于某些诸如算法复杂度过高等问题根本无法解决。
|
|
|
|
糟糕的数据库设计是导致单一事务响应时间过长的最重要原因。通常,数据库设计在系统开发初期进行,此时,数据库设计人员往往对数据的实际规模和特性没有足够的了解。在数据库设计方面,对响应时间影响较大的因素有数据库表的规模、索引的使用、数据的分布、查询优化等。其中索引的使用极大影响事务执行的响应时间。实际上,很多情况下应用程序在访问大规模数据库表时的确没有使用索引。造成这种情况的原因通常是开发人员的疏忽,也有用户的需求变化过多,某些数据库字段不适合建立索引的情况。在这里需要特别指出的是,对组合索引进行查询时,查询条件中字段的顺序与数据库设计的索引字段顺序要一致。如果顺序颠倒,组合索引根本不能被数据库使用。例如,表A(field1, field2, field3),有组合索引index(field1, field2),诸如
|
|
|
SELECT * FROM A WHERE((field2=condition2)AND(field1=condition1))和SELECT * FROM A WHERE(field2=condition2)的查询无法使用index索引。此外,并非增加索引就一定能够提高单一事务执行的响应时间。过多的索引使用将极大地增加插入操作(INSERT)的花费,从而使响应时间变长。
|
|
|
数据库表规模过大,是指单一数据库表的记录数在百万行以上,对这类表直接进行检索而不采取必要的优化手段,必然造成单一查询响应时间过长。如果数据库表的规模一再增大,使用索引也不能很有效地解决响应时间过长的问题。对此类问题,可能的解决办法是对数据进行分布,使查询能够并行执行或缩小查询的范围。目前,主流关系数据库管理系统都提供表分区(分段)存储,以使得软件开发人员比较容易地实现数据分布。
|
|
|
查询优化对响应时间的影响也不容忽视,尽管优化活动由数据库管理系统完成。实际上一条结构化查询语句(SQL)的写法有很多种,不同的写法可能有不同的响应时间,这一差别可能非常大。如果开发人员在软件编写过程中恰好使用了执行效率低的SQL语句,其响应时间自然就会变长。目前,某些独立软件开发商已经注意到这种情况,并开发了相应的软件帮助应用软件开发人员找到执行最快的SQL语句的写法。但是,由于数据库本身是动态变化的,执行最快的SQL语句也可能变化,所以这种方法也是有局限性的。
|
|
|
|
事务粒度过大指单一数据库事务执行过程中,需要以某种并发控制机制访问多个数据库资源。通常采用的并发控制机制是互斥锁或者共享锁。这种大粒度事务的执行由于要访问多个数据库资源(如数据库表),本身就需要消耗相当长的时间。此外,由于通常事务在执行的时候会对数据库资源进行加锁,这类事务也对其他访问该资源的用户造成影响。由于这类事务通常使用的锁数量都在两个以上,如果不合理地进行控制,极容易造成死锁。因此,在应用软件设计过程中,应该尽量消除大粒度事务。
|
|
|
|
批任务是指一次操作将对数据库中大量数据进行互斥访问的数据库事务。这种类型的事务通常将更新同一个数据库表中的数千项乃至更多的数据。由于这类任务把所有操作放置在同一个数据库事务中,所访问的资源在其执行过程中始终被锁定,必然会对其他普通事务造成访问影响。此外,由于这类任务本身将对数据库服务器造成巨大的负担,使得服务器负载加重,从而影响独立事务的响应时间。通常情况下,批任务推荐在系统具有较长空闲时完成(如晚上),这样可以保证不对独立事务造成影响。如果由于业务的要求,批任务必须与独立事务混合运行,则必须对其加以改造,以减轻对其他事务的影响。
|
|
|
|
并发处理能力差是指应用系统在执行同一类型事务的多个实例时,不能获得与执行实例数量相当的吞吐量,而是大大低于理论值。一般来说,这类问题都是由于互斥访问造成的,即并发执行中的某个实例以互斥方式对资源进行访问,造成了其他同类型用户必需等待该实例释放锁定资源后才能执行。应该指出,由于某些资源必须以互斥的方式进行访问,某些类型的事务在同一时间是只能有一个进行执行的。对于并发处理能力差的问题,可能的解决方法有,降低同一类型事务中锁的粒度、优化应用逻辑以缩短单一类型事务响应时间等。
|
|
|
|
锁冲突是每个以关系数据库为核心的信息系统必须解决的问题。这里的锁冲突是指同一类型或不同类型事务在并发执行的情况下,由于资源互斥而相互影响,造成一个或多个事务无法正常执行的情况,包括资源锁定造成的数据库事务超时和死锁两个方面。
|
|
|
|
资源锁定导致的数据库事务超时,其原因是多方面的,其中,批任务影响其他类型独立事务的情况占有相当大的比重。此外,某些改造过的批任务由于频繁对特定资源进行锁定,也会对独立事务造成相当大的影响。如果在设定时间内,数据库服务器由于资源锁定没有能够完成客户端发出的操作请求,数据库服务器将通知被锁定的客户端该操作超时。
|
|
|
某些大粒度事务在并发执行的实例较多时也会造成同类或不同事务的数据库超时。
|
|
|
此外,应用系统如果没有健壮的异常处理机制,很可能造成锁资源不被释放(即,开始的事务既没有提交也没有回滚)。当这种错误发生时,必然造成资源被长久锁定。对此类问题,应用系统在开发的过程中需要采取一套完善的异常处理机制,确保资源不被长期锁定。
|
|
|
|
由于数据库死锁可以看作进程间死锁的一种特殊情况,我们可以采取与处理操作系统死锁相类似的方法解决数据库死锁的问题。造成死锁必须具备下述条件(Coffman et al 1971):
|
|
|
①互斥条件。每一个资源或者被分配给特定的进程,或者可用。
|
|
|
②持有并等待条件。被授权持有资源较早的进程可以请求新的资源。
|
|
|
③不可取代原则。事先被赋予的资源不能够从该进程被强制取走,它们必须被所持有的进程明确释放。
|
|
|
④环等待条件。必须存在两个或者多个进程的环形链,其中每一进程都等待由环形链的下一个成员所持有的资源。
|
|
|
由于软件开发人员对资源争用可能造成的死锁问题往往没有充分考虑,而目前主流数据库管理系统主要采用乐观的并发控制算法,导致应用系统实际使用过程中频繁发生死锁。应该说明,同类型数据库事务的不同实例之间由于访问资源的顺序一致,通常情况不会发生死锁;不同类型事务之间如果没有按照一个统一的契约进行并发访问,将极容易形成死锁。因此,在确保应用系统功能的前提下,制定一个不同事务之间进行并发访问的原则,就可以有效消除环等待,减少死锁发生的可能性。
|
|
|
针对数据库的性能问题,一般应采用什么样的解决办法呢?
|
|
|
在对数据库服务器常见性能问题进行充分研究的基础上,我们制定了一套适用于解决已发布系统性能问题的通用方法,步骤如下:
|
|
|
|
|
|
④对规模较大的数据或者无法通过一般优化解决的锁冲突进行分布。
|
|
|
必须指出,解决数据库性能问题是一个迭代和往复的过程,通常需要在各种条件的矛盾之间寻求最佳的平衡点。
|
|
|
|
对数据库服务器软件、操作系统、网络环境乃至客户端等各类处理单元的性能相关信息进行监视并记录,是发现数据库性能问题的基础。这一步骤的作用是搜集与数据库服务器性能表现密切相关的数据,作为分析性能问题的基础。由于各个处理单元的状态是随着时间的推移而动态变化的,性能数据的监视与采集必须尽可能详细地记录下所有时间点上各个处理单元的状态信息。为此,我们采取对各个采样时间点的处理单元状态信息进行快照方式,来对性能相关数据进行监控和记录,相邻采样时间点之间的间隔越小,状态信息就越准确。
|
|
|
在各类监视活动中,对数据库服务器软件性能属性的监视是整个活动的重点,主要集中在数据库会话的状态信息、执行的结构化查询语句和锁使用情况等方面。其中,状态信息代表了单一数据库会话在其生命周期中的状态变化情况,包括在哪一个时间点开始一个事务,在哪一个时间点被其他会话锁定,何时超时等。执行的结构化查询语句代表单一数据库会话在其生命周期中执行的所有数据库操作。锁使用情况代表整个数据库服务器的锁资源使用和变化情况。此外,顺序扫描、高代价查询等属性也是代表数据库服务器性能的重要数据。
|
|
|
|
通过对数据库锁使用情况和SQL语句的执行历史进行分析,可以发现一个事务同时占用大量数据库锁的应用逻辑事务。通常这类事务都属于批任务。由于批任务本身的特性,决定了在其整个执行过程中,必然消耗大量资源,最好将其放置在系统具有充分空闲时间时进行。
|
|
|
|
如果应用系统锁冲突频繁发生,那么该系统的性能表现不可能令人满意。导致这种问题的原因非常复杂,主要表现在事务粒度过大、响应时间过长、异类事务互相影响并形成死锁等情况。通过对数据库锁使用情况信息的分析,可以定位发生锁冲突的各个会话;在此基础上对发生锁冲突的会话各自的执行状态变化和结构化查询语句进行分析,可以定位发生锁冲突的应用逻辑源程序。如果造成锁冲突的是同种或者异种普通事务,必须对其本身特性加以分析,确定是否本身粒度过大,数据访问是否存在瓶颈等。对这类事务的优化相对较难,一般需要开发人员的经验和对应用逻辑本身特性的了解。
|
|
|
|
数据分布的主要目的是,通过数据库服务器的并行执行特性,使得单一事务的执行具有较短的响应时间和不同类的事务之间影响相对缩小。在缩短响应时间方面,这种方法主要适用于对规模较大的数据库表进行访问的情况。它不仅使得特定的查询可以并行执行,而且有可能改变结构化查询语句的执行计划,缩小查询进行的范围。此外对于异类事务之间,或者同类事务的不同实例锁冲突频繁的问题,可以通过数据分布加以解决。
|
|
|
数据库性能问题通常表现在响应时间过长,并发处理能力差和锁冲突严重等方面,其原因是多方面的。本书提出的通过监视并记录应用系统处理单元性能相关数据,来定位性能问题的方法,可以帮助开发人员有效发现系统中存在的主要性能问题。必须指出,解决数据库性能问题是一个迭代和往复的过程,通常需要在各种条件的矛盾之间寻求合理的平衡点。
|
|
|
|
下面将以Oracle为例,讨论数据库优化的一些方法,对于其他的数据库,由于其实现的机制以及特性可能与Oracle不同,那么优化的方法也会有所不同,大家可以参照其手册,进行分析。
|
|
|
虽然这些方法属于数据库开发人员或者数据库管理人员优化系统的方法,但是如果测试人员了解这些方法,就可以更好地分析、定位数据库性能问题,制定有针对性的测试用例。
|
|
|
Oracle与提高性能有关的特性主要包括:索引、并行执行、簇与散列簇、分区、多线程服务器以及同时读取多块数据等。下面分别进行介绍。
|
|
|
这里列出了Oracle配置的关键参数以及其使用方法。
|
|
|
①max_dspatchers:指定了系统允许同时进行的调度进程的最大数量。
|
|
|
②max_shared_servers:指定了系统允许同时进行的共享服务器进程的最大数量。如果系统中出现的人为死锁过于频繁,那么管理员应该增大这个参数的值。
|
|
|
③parallel_adaptive_multi_user:当该参数的值为true时,系统将启动一个能提高使用并行执行的多用户系统性能的自适应算法。这个算法将根据查询开始时的系统负载自动降低查询请求的并行度。
|
|
|
④parallel_automatic_enabled:如果将该参数的值设置为true,那么Oracle将确定控制并行执行的参数的默认值。
|
|
|
⑤parllel_broadcast_enabled:该参数允许管理员提高散列连接和合并连接操作的性能,在这样的连接操作中,系统将一个大尺寸的结果集与一个小尺寸的结果集连接在一起(在合并操作中,数据的尺寸是根据字节数而不是记录数确定的)。
|
|
|
⑥parllel_execution_message_size:这个参数指定了系统并行执行时的消息尺寸(在Oracle的旧版本中,这个概念是指并行查询、PDML、并行恢复和并行复制数据等)。
|
|
|
⑦parllel_max_servers:指定了实例能同时运行的并行执行进程和并行恢复进程的最大数量。随着用户需求的增长,在创建实例时,为这个参数设置的值将不再能满足用户需求,所以应当增大这个参数的值。
|
|
|
⑧ parllel_min_percent:系统将联合使用parllel_max_servers、parllel_min_servers和该参数。这个参数允许指定并行执行进程(即参数parllel_max_servers之值)的最小百分比。
|
|
|
⑨parllel_min_servers:这个参数指定了实例并行执行进程的最小数量。其值就是实例启动时Oracle创建的并行执行进程数。
|
|
|
⑩parllel_threads_per_cpu:指定了实例默认的并行度和并行自适应以及负载平衡算法。它指明了并行执行过程中一个CPU能处理的进程或线程数。
|
|
|
?partition_view_enabled:指定了优化器是否使用分区视图。Oracle推荐用户使用分区表(这是在Oracle8之后引入的)而不是分区视图。分区视图只是为了提供Oracle的后向兼容性。
|
|
|
?revovery_parallelism:这个参数指定了恢复数据库系统时使用的进程数。
|
|
|
|
在数据库系统中,索引是一种可选结构,其目的是提高数据访问速度。利用索引可提高用户访问数据的速度,或直接从索引中独立检索数据。如果对索引的配置和使用进行了优化,那么索引能大大降低数据文件的I/O操作并提高系统性能。
|
|
|
但是在为一个表创建索引之后,Oracle将自动维护这个索引。当用户在表中插入、更新或删除记录时,系统将自动更新与该表相关的索引。一个表可以有任意数量的索引,但一个表的索引越多,用户在该表中插入、更新或删除记录时所造成的系统开销也越大。其原因是无论何时更新表,系统都必须更新与之相关的索引。
|
|
|
索引是建立在表的一个或多个字段之上的。索引的作用大小取决于该字段或字段集的选择性。所谓选择性,是指索引能降低数据集中的程度。如果表中与某个索引相关的字段值各不相同,那么该索引就有很好的选择性。一个选择性很差的索引的例子,是基于字段值仅为true/false的字段创建的索引,因为表中很多记录该字段的字段值都相同。一个索引可能只能帮助管理员降低检索的记录数,而不能惟一地确定一条记录。例如:如果为一个表的LastName字段创建了一个索引,现在用户需要搜索John Smith,那么这个索引将返回LastName字段值为Smith的所有记录,因而用户还不得不在返回的记录中搜索含John的记录。索引的选择性越好,就越有助于降低返回记录的数量,从而提高数据访问速度。下面介绍有效创建和使用索引的技巧和方法。
|
|
|
|
索引的主要作用之一就是降低系统处理的数据量。对CPU使用和等待完成I/O操作的时间上,I/O操作引起的系统开销都是非常昂贵的。降低I/O操作可提高系统性能和处理能力。如果不使用索引,那么为了找到特定的数据,系统将不得不扫描表中的所有数据。
|
|
|
|
|
如果不使用索引,系统必须扫描整个emp表并检查表中每条记录的employee_id字段的值。如果emp表很大,那么这个操作可能意味着数量巨大的I/O读写和很长的处理时间。
|
|
|
如果为emp表的employee_id字段创建了索引,那么系统将遍历该索引并找到用户所查询记录的ID。找到记录ID之后,只需一条额外的I/O操作就能检索到用户所需的数据。
|
|
|
用于说明这个问题的最好例子,是只需查找一条记录的情况。在表的每条记录中,类似employee_id这样的字段的值可能在整个表中都是惟一的。这意味着查询结果值返回一条记录,这种查询的效率是非常高的。
|
|
|
在某些情况下,索引必须返回大量数据。如下面的例子:
|
|
|
|
这个查询语句很可能返回大量数据,因为索引操作返回了大量记录的ID,并且系统必须独立访问这些记录的ID,所以这种情况下,不使用索引可能比使用索引的效率更高,直接进行表扫描可能效率更高。不同情况下,采用哪种查寻方法更好,很大程度上取决于表的数据量和组织形式。
|
|
|
对于不同的数据,在某些情况下位图索引可能非常有用,而在另外一些情况下,使用位图索引可能没有任何好处。
|
|
|
|
如果对表创建了索引,那么更新、插入和删除表中的记录都将导致额外的系统开销。在系统提交这些操作之前,系统将会更新所有与该表相关的索引。这可能需要花费很长时间,并额外增加一定的系统开销。
|
|
|
|
在某些情况下,表中的某些字段的选择性可能很低。开发人员没必要为所有表创建索引,实事上,在某些情况下索引引起的问题比解决的问题更多。在很多情况下,需要反复试验,才能确定一个索引是否有助于提高系统性能。
|
|
|
但是,位图索引能在字段选择性不高的情况下工作得很好。一个位图索引可以和其他位图索引联合使用,以降低系统检索的数据集。对于某些值为true/false、yes/no或其他小范围数据的字段,建立位图索引是非常合适的。请记住:位图索引所占用的空间,是随着与该索引相关的字段的不同值的数量的增加而增加的。
|
|
|
如果决定创建一个索引,那么确定为哪些字段创建索引是非常重要的。对于不同的表,可能会选择一个或多个字段创建索引。可使用如下方法来确定在哪些字段上创建索引:
|
|
|
①选择那些最常出现在where子句中的字段。经常被访问的字段最可能受益于索引。
|
|
|
|
③必须注意索引导致的查询语句性能的提高与更新数据时性能的降低之间的平衡。
|
|
|
④经常被修改的字段不适合创建索引,其原因是,更新索引将增加系统开销。
|
|
|
在某些情况下,使用复合索引的效率可能比使用简单索引的效率更高。下面的一些例子说明了应当在何种情况下使用复合索引。
|
|
|
①某两个字段单独来看都不具有惟一性,但结合在一起却有惟一性,那么这种情况下,复合索引将工作得很好。例如:A字段和B字段都几乎没有惟一性值,但绝大多数情况下,字段A和B的某个特定组合却具有惟一性特点。那么在检索数据时,可在where子句重视and操作符来将这两个字段连接在一起。
|
|
|
②如果select语句中的所有值都位于复合索引中,那么Oracle将不会检索表,而直接从索引中返回数据。
|
|
|
③如果多个查询语句的where子句中作为查询条件的字段都不相同,但返回的记录相同,那么应当考虑利用这些字段创建一个复合索引。
|
|
|
在创建索引之后,开发人员应当定期利用SQL TRACE工具或EXPLAIN PLAN来察看用户查询是否充分利用了索引。很有必要花费一定精力来试验使用索引和未使用索引在效率上的差别,以判断索引所耗费资源是否物有所值。
|
|
|
应该删除那些不经常使用的索引。可使用alter index monitoring usage语句来跟踪索引的使用情况。还可以从系统表all_indexes、user_indexes和dba_indexes中查询用户访问索引的频率。
|
|
|
如果为一个不适合创建索引的字段或表创建了索引,那么这可能会导致系统能力的下降。而如果创建的索引合理,那么这将降低系统的I/O操作并加快访问速度,从而大大提高系统性能。
|
|
|
|
Oracle9i的并行执行特性就是Oracle旧版本中读者熟知的并行查询选项。而在Oracle9i中,这个特性已内嵌在Oracle RDBMS中。
|
|
|
为什么要实现并行执行?RDBMS的绝大多数操作都可分为以下3类:
|
|
|
①被CPU限制的操作:这类操作的速度和单CPU运行速度一样。通过并行化操作,多个CPU可并行处理系统负载,因此可以更快完成该操作。
|
|
|
②被I/O限制的操作:这类操作花费了绝大部分时间等待系统完成I/O操作。当系统中同时出现多个I/O请求时,绝大多数raid控制器将很好地工作。另外,当一个线程需要等待完成I/O操作时,可充分利用CPU来处理另一线程的CPU部分。
|
|
|
③被竞争限制的操作:并行处理不能改善由资源竞争所限制的操作。
|
|
|
对表扫描而言,系统花费在等待数据从磁盘返回的时间常常比处理数据所花费的时间还长。通过并行机制,可用多个服务器进程处理查询操作,从而弥补了系统在这方面的问题。当一个进程在等待I/O操作时,CPU可执行另一个进程。如果数据库系统运行在对称多处理器(Symmetric Multiprocessor, SMP)计算机、计算机群集或大规模并行处理(Massive Parallel Processing, MMP)计算机上,那么开发人员可充分利用并行处理机制的优势。
|
|
|
并行执行使Oracle的某些功能由多个服务器进程协同处理成为可能。这些功能包括查询、创建索引、加载数据和恢复数据库。所有这些功能都遵循一个共同规则,即充分利用CPU资源。
|
|
|
|
并行查询处理允许多个服务器进程以并行方式处理某些Oracle语句。
|
|
|
并行查询操作将该查询分为几个不同的部分,每部分由不同的服务器进程进行处理。这些进程称为查询服务器。一个被称为“查询协调者”的进程负责调度这些查询服务器。系统将一个SQL语句和一个并行度提交给查询协调进程,而协调进程则负责将该查询分配给查询服务器,并将每个查询服务器返回的结果组合成一个整体。并行度是指分配给该查询的查询服务器数量。Oracle服务器能对连续、排序以及表扫描操作实现并行执行。
|
|
|
在多处理器或并行处理计算机上,并行查询操作是非常有效的;在单处理器计算机上,如果大部分时间都花在了等待系统完成I/O操作上,那么使用并行查询也是非常有效的。具有足够I/O带宽的系统,尤其是使用磁盘阵列的系统,都能够从并行查询操作中受益。
|
|
|
如果通常情况下系统CPU的使用率达到了100%,并且系统中只有少量磁盘驱动器,那么使用并行查询是没什么意义的。同样,如果系统的内存非常紧张,那么并行查询也没有多大意义。
|
|
|
在并行查询中,合理的I/O分布和并行度是最需要调整的两个方面。对并行度的调整一方面需要反复的试验,另一方面还需要一定的分析。应当首先根据如下一些因素考虑并行度。
|
|
|
①计算机的CPU能力:CPU的数量和能力将影响系统能运行的查询进程数量。
|
|
|
②系统处理大量进程的能力:一些操作系统能处理很多并发进程,而另一些操作系统则没有这方面的能力。
|
|
|
③系统负载:如果系统现在的运行已经达到了极限,那么对并行度的调整不会有太大效果。如果系统运行已达其能力极限的90%,那么太多的查询进程将使系统不堪重负。
|
|
|
④系统处理的查询数量:如果系统的大部分操作是更新操作,但仍有少量的重要查询存在,那么开发人员可能希望系统运行多个查询进程。
|
|
|
⑤系统的I/O能力:如果磁盘上的数据是分片或是使用磁盘阵列存储的,那么系统能够处理多个并行查询。
|
|
|
⑥操作类型:系统是否需要处理很多的全表扫描或排序?并行查询服务器非常有助于这类操作。
|
|
|
这些因素对系统采用的查询并行度有一定影响。下面是关于并行度的另一些建议。
|
|
|
①诸如排序之类的,需要大量CPU资源的操作应当采用较低的并行度。其原因是这类受限于CPU的操作已经充分利用了CPU,而不需等待系统的I/O操作。
|
|
|
②诸如全表扫描之类的,需要大量磁盘I/O的操作,应当采用较高的并行度。需要等待磁盘I/O的操作越多,系统就越能受益于并行操作。
|
|
|
③如果系统中有大量的并发进程,那么应当采用较低的并行度。因为太多的进程将使系统不堪重负。
|
|
|
在确定使用并行操作之后,读者可通过查询动态性能视图V$PQ_SYSSTAT来监控系统。
|
|
|
|
并行查询的另一个特征是以并行方式创建索引的能力。通过这个特性,系统用于创建索引的时间将大大减少。类似于并行查询操作,并行创建索引操作也有两组查询服务器。其中一组查询服务器的功能是扫描需要创建索引的表,以获得ROWID和与索引相关的字段值;另一组查询服务器则对第一组查询服务器所得到的值进行排序,并将排序后的结果传递给协调进程。而协调进程再根据这些排序之后的条目创建B树索引。
|
|
|
|
通过使用多个并发会话同时往同一个表中写数据,可实现数据加载的并行化。对于不同的系统配置,通过并行方式加载数据,可以提高数据加载性能。因为加载数据不仅需要大量的CPU资源而且还需要大量的I/O操作,所以并行化数据加载将提高数据加载的性能。并行化数据加载将通过多个直接加载器进程实现。
|
|
|
并行加载数据是非常有用的,特别是在数据加载时间很紧张的环境中尤其如此。通过将每个输入文件放置在不同的卷上,可提高并行加载数据的性能。并行查询操作中所有的通用调整原则都是用于并行加载数据操作的。
|
|
|
|
并行恢复是并行查询选项的一个非常重要的特性。在评估Oracle和测试软硬件时,需要有意地使系统崩溃,以检验系统的可恢复性。通过使用并行恢复选项,恢复数据库和实例的时间将大大缩短。当被恢复的系统有很多磁盘并支持异步I/O操作时,系统恢复所用的时间将会大大缩短。对于只有很少磁盘的小系统或不支持异步I/O的系统,采用并行方式恢复系统是不明智的。在并行恢复方式中,一个进程负责从重做日志中读取和调度重做入口,并将这些入口传递给恢复进程。而恢复进程则负责将用户对数据库所作的修改写进数据库中。
|
|
|
总之,在平衡操作负载方面并行查询选项是非常有用的,当其他进程在等待系统完成I/O操作时,并行查询可使CPU转而处理其他进程,从而充分利用系统的CPU资源。对于多处理器计算机,使用并行查询是非常有用的,但这并不是说并行查询不能用于单处理器计算机。
|
|
|
|
簇(cluster),有时被称为索引簇,是Oracle数据库中用于存储表的一种方法。在一个簇中,系统将多个相关的表存储在一起,以缩短用户访问相关记录的时间。只有当这些相关表经常被同时访问时,才适合使用簇。对用户和应用程序而言,簇的存在是透明的,簇只影响数据的存储方式。
|
|
|
在某些情况下使用簇是非常有利的,而在另外一些情况下,使用簇却可能非常不利。应当仔细考虑簇是否有助于提高系统性能。一般而言,如果集中存放的数据主要用于连接表中,那么使用簇是很好的。如果两个表存放了相关数据,并且这两个表经常被同时访问,那么通过使用簇可将相关数据预装入SGA中,从而提高用户访问数据的性能。因为开发人员经常同时使用这两个表,所以在用户访问其中一个表时,将另一个表的数据也放入SGA中,可大大缩短用户访问数据的时间。如果一般情况下开发人员不会同时使用这些信息,那么簇将不能提高系统性能,并且这种情况下,簇实际上会导致系统性能的轻微下降,其原因是额外的表信息将占据更多的SGA空间。簇的另一个不足之处在于,当用户执行insert语句时将降低系统性能。引起性能下降的原因是簇在使用存储空间上采用的方法更加复杂,并且系统需要将多个表存储在同一个数据块中。簇表比单个表占用了更多的存储空间,这将导致系统扫描更多的数据。另外如果系统经常对这些表中的某一个表作全表扫描,那么不应当为这些表创建簇。因为如果创建了簇,那么额外数据将占用SGA的部分空间并导致额外的I/O操作,这两方面的原因都会降低系统性能。
|
|
|
|
散列簇和簇非常相似,但散列簇采用散列函数而不是索引访问簇键。散列簇根据散列函数的计算结果保存数据。散列函数是一个数学函数,这个函数根据散列键的值来确定簇中的数据块。
|
|
|
尽管可以以类似于索引簇的方式创建散列簇,但不必为所有表创建散列簇。实际上,更经常做的是为一个单独的表创建散列簇,以利用散列簇的特性。通过使用散列索引,系统只需一次I/O操作,系统就能检索到用户所需数据,如果使用B索引,系统需要多次I/O操作才能检索到需要的数据。适合创建散列簇的表应具有以下特征:
|
|
|
|
|
|
|
一个适合于创建散列簇的典型例子是一个用于存储零件信息的表。通过建立一个关于零件号的散列键值,用户对该表的访问将非常有效而且非常快。任何时候,如果系统中有一个静态的表,其中的一个或多个字段的值具有惟一性特征,那么可考虑为这样的表创建散列簇。
|
|
|
和索引簇一样,使用散列簇既有优点也有不足。当用户使用关于簇键的等式查询检索数据时,散列簇具有很高的效率。如果用户不是根据簇键值检索数据,那么这个查询就不能被散列化。这就像在索引簇中见到的那样,当在散列簇表中使用insert语句时,将降低系统性能。
|
|
|
|
当系统执行表扫描时,Oracle具备同时读取多个数据块的能力,这种能力提高了系统的I/O速度。通过同时读取多块数据,Oracle能够从磁盘上读取更大的数据块,从而避免了对磁盘上数据进行搜索的操作。通过降低磁盘搜索和读取更大的数据块,可以降低系统的I/O开销和CPU开销。
|
|
|
Oracle的这个特性被称为多块读取。只有对于连续数据块,多块读取特性才有助于提高系统性能。通常情况下,一个盘区内的数据块都是连续的。如果数据存放在多个小盘区上,那么多块读取的性能将会降低。
|
|
|
Oracle初始化参数db-file-multiblock-read-count指定了一次多块读取能读取的数据量。因为这个参数几乎不会导致系统性能的下降,所以一般情况下,都将这个参数的值设置得很高。I/O的尺寸取决于初始化参数db-file-multiblock-read-count和db-block-size的值。
|
|
|
为了充分发挥多块读取数据的优势,应当尽量配置自己的系统以使数据库的块尽可能都是连续的。为了做到这一点,应当使用优化尺寸的盘区来创建数据库。盘区的尺寸应当远大于一次多块读取操作所读取的数据的尺寸。
|
|
|
|
分区(partition)这一特性的目的是允许大尺寸表或索引分解成小的更容易管理的部分,即分区。与原来的表或索引相比,因为分区变小了,所以系统访问分区的速度更快、效率也更高,可将分区想象成表或索引被分解之后的多个小尺寸的表或索引。系统可单独访问这些小尺寸的表或索引,也可以以组或整体方式访问之。
|
|
|
可使用多种分区方案来创建分区。这些方案确定了如何将数据分解成分区。可使用如下一些方案。
|
|
|
. Range Partitioning:这种方案根据数据的范围,比如月、年等对表中的数据进行分区。
|
|
|
. List Partitioning:这种方案和Range Partitioning分区方案很类似,但这种方案是按照数据的值,而不是数据的范围来进行划分的。
|
|
|
. Hash Partitioning:这种分区方案使用散列函数来实现对数据的自动分区。
|
|
|
. Sub-Partitioning:这种方法就是开发人员熟悉的复合分区方法。这种方法允许开发人员同时使用多种分区方案。
|
|
|
|
. 对能被分区的大尺寸表进行扫描时,分区可降低I/O操作和CPU的使用率。
|
|
|
|
. 能以删除分区的方式删除数据,而不必使用select语句来删除大量数据。
|
|
|
|
|
|
|
用户可通过专用服务器进程连接到Oracle实例,也可以通过多线程服务器进程连接到Oracle实例。因为每一个专用服务器进程都将占用大量内存资源和系统资源,所以有必要对多用户连接采用多线程服务器进程。
|
|
|
多线程服务器进程允许多个用户使用一定数量的共享服务器进程。所有对共享服务器的请求都必须经过调度进程,这个过程对SGA大缓冲池中的用户对共享服务器进程的请求进行排队。当系统处理完用户请求后,系统通过SGA中的大缓冲池将请求结果返回给调度进程。
|
|
|
因为共享服务器进程使用共享缓冲池对用户请求进行排队并返回数据,从而大大减少CPU和内存的使用。然而,正如读者所猜想的那样,多线程服务器也会增加系统开销。这就是为什么执行需要很长时间的批处理作业时,使用专用服务器的原因。
|
|
|
对配置和调整多线程服务器,需要调整参数文件中的参数。还应当小心监控系统的大缓冲池,以确保系统的运行没有超出分配给它的内存空间。
|
|
|
应当尽量监控只有少量用户的共享会话所使用的内存。监控结果将会告知共享会话使用了多少内存。利用这些数据,就能估算所有会话总共需要多少内存。可通过下面的SQL语句获得这些信息:
|
|
|
|
上面语句的输出结果告诉开发人员使用了多少内存。将使用的总内存量除以连接数,就可确定每个会话使用的内存数量。然后就可从每个会话使用的内存量来推算为了支持系统的所有会话,需要为系统的大缓冲池分配多大内存空间。
|
|
|
如果认为大缓冲池的内存太少,那么可通过调整初始化参数large_pool-size来增加大缓冲池的内存空间。请记住:除多线程服务器之外,系统还使用大缓冲池来执行并行查询操作。
|
|
|
初始化参数mts_dispatchers决定了每个网络协议使用的调度进程的数量。通过提高这个参数的值,可能会看到用户会话的性能得到了提高,其原因是用户会话不再需要等待可用调度进程。
|
|
|
除前面讨论的参数之外,还有如下一些参数与多线程服务器有关。
|
|
|
. mts_max-dispatcher:实例能创建的调度进程的最大数量。这里的调度进程包括所有网络协议的调度进程。
|
|
|
. mts_servers:实例刚启动时的共享服务器进程数。如果将这个参数设置为0,那么Oracle将不会是用共享服务器进程。为了满足系统需要,共享服务器进程的数量将会动态增长。
|
|
|
. mtx_max_servers:这个参数指定了实例中允许运行的共享服务器进程的最大数量。
|
|
|
如果应用程序能利用簇和索引的优势,那么簇和索引将有助于提高系统性能。如果应用程序使用了索引而又需要频繁更新数据,那么这样的索引将会降低系统性能,其原因是在数据更新的同时,系统也需要更新索引。同样地,如果用户的数据访问模式使用了簇,那么簇将会有助于提高系统性能;反之,簇将会成为系统的负担。
|
|
|
Oracle并行查询选项和并行服务器选项能极大地提高系统性能。通过将查询分配成多个服务器进程,并行查询选项提供了一种提高系统CPU使用率的机制。并行服务器为开发人员提供了一个健壮的可升级的服务器群集功能,这个特性不仅能提高系统性能,还为系统提供了立即排除错误的能力。应用程序和需求将决定这些特性是否有助于提高系统性能。在调整系统时,非常重要的一点是需要注意调整系统所冒的风险。在前面的内容介绍中,我们讨论了不同的系统调整主体,例如共享内存池的尺寸和数据块缓冲区等。提高共享内存池和数据库缓冲区的尺寸将会提高缓冲区的命中率,但这样的调整也存在着损害系统性能的风险。然而,如果读者对某些系统特性配置得不正确,那么它们对系统性能造成的负面影响会更大。任何时候调整系统,都应当预先估计该调整所面临的风险,特别是在没经过详细测试就对生产系统进行调整时更是如此。
|
|
|
如果对系统需要调整的方面和该调整所影响的方面进行了仔细考虑,并对应用程序的数据访问模式有深入的了解,那么可以将调整面临的风险降到最小。应当仔细考虑对系统所作的修改将会对系统造成的影响,并尽量了解系统修改对应用程序的影响。只有这样,才能在优化系统性能的同时,将系统调整的风险降到最低。
|
|
|
|
一般情况下,在测试的标志性阶段或者测试结束时需要出具测试报告,测试报告是整个测试的总结,其主要作用是描述测试结果。测试报告的格式可以不拘一格,但需要验证是否包括以下关键内容:
|
|
|
|
|
|
|
|
|