Oracle数据库性能优化的艺术(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-10 15:26:57

点击下载

作者:文平

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Oracle数据库性能优化的艺术

Oracle数据库性能优化的艺术试读:

前言

数据库技术在IT系统中的广泛应用已不少于二十年。在这二十几年中,我们看到了数据库技术的起承与转合,产品的此消和彼长,供应商的发展或萎缩。太多的变化使我们有些茫然,快速的更迭使我们疲于奔命,作为数据库从业者,我们在技术方向上应该如何跟随?我们的行动方法应该如何适应?

这是一个大问题!

辩证法中很朴素的两条准则也许能帮到我们:第一,区分现象和本质;第二,要用系统的方法论来分析问题。

这点对于数据库优化工程来说更为重要!为什么这么说呢?

随着这二十年的IT应用持续深入,数据库的应用已经进入了相对成熟的时代。作为IT基础设施的核心组成部件,数据库早已不是可以孤立存在的系统——它与服务器系统、存储系统、网络系统等硬件紧密相连,它与操作系统、中间件系统、应用编码等软件紧密相连,它与用户访问模式、用户使用频度、数据承载压力紧密相连。这种多重关联特性决定了数据库性能的评估与优化就是一门综合的技术与艺术,是一项相当严密的系统工程。在这个系统工程中,我们需要透过各种表象进行全系统评估从而了解实质,并在最后得到相对精确和有效的结论与措施。

那么,能不能找到一种“具有普世意义的药方”呢?

很遗憾,我认为这种想法没有任何存在的可能性!IT应用的显著特点就是需求个性化、部署个性化、使用个性化。在这个高度个性化的环境中,提炼出一个普遍适用的数据库性能优化准则肯定是不可行的。

但这并不是说没有规律可循,或者说,“具有普世意义的流程”是存在的,这个流程可以包括如下的关键环节——从什么样的角度切入性能问题,如何保证数据库运行效率与IT系统中其他联动部件保持协调,数据库性能优化的工程过程要有哪些阶段。该流程并未局限于数据库内部,性能优化是要围绕IT应用整体来展开的。

具体说来,对于面向性能的优化,大家需要有四个共识。第一个共识是,要充分意识到这是一个全局问题,这是一个应用程序、部署方式、存储设备、服务器设备、网络拓扑、操作系统、数据库系统等全员参与的优化问题。由于很多问题是在数据库以外的,这要求性能分析和优化人员具有完整的知识体系——这是一个巨大的挑战。但是没有办法,IT系统中的任何一点都可能是性能问题的麻烦制造者。在这点上,局部的观点要服从全局的观点——从系统工程角度来看待问题。

第二个共识是,需要在设计阶段讨论性能问题,并及时做好性能风险上的应对策略。这里的设计不仅仅指应用的架构设计,还特指应用中的数据库逻辑结构设计与物理结构部署。数据库设计中的需求实现以及设计中的优化考虑,是数据库性能优化的基本决定要素。如果不能在设计上考虑优化要素,那么这样的架构设计就是先天不足的架构设计。

第三个共识是,需要在开发阶段讨论性能问题。很多工程案例告诉我们,应用的编码构成决定了应用在性能方面的主要特征。同样的应用逻辑,不同的代码实现,其效率可能是不同的。编写性能可以达到最佳同时系统开销最小的应用模块,是编码中事关性能的主要任务。但遗憾的是,在大多数系统中,由于编程人员的技术素质、项目完成工期上的压力、项目预算上的限制等缘由并未做完整的优化处理。

第四个共识是,在数据库性能优化工作中,如果系统处于运行阶段,这时优化人员的手段是极其有限的,优化效果和作用也相对具有局限性。从优化工作的贡献率来说,数据库调优成本会随着IT应用的生命周期进程而增加,但调优收益却是同步降低并逐渐趋于零的。

阅读本书之前,我们需要建立如上的几个共识,因为本书就是按照这样的共识和这样的顺序完成写作和表述的。

本书主要介绍的是Oracle数据库应用系统的优化问题,但是本书的技术观点不限于此,对于其他数据库(DB2也好,SQL Server也好,或者是MySQL、PostgreSQL等中小规模数据库也好)来说,本书的技术观点同样适用。

本书从前至后分为若干部分来描述数据库性能系统工程中的若干环节。其中的第一个环节便是数据库设计问题。把该问题作为本书的首要描述内容,就是因为最优的性能来源于最恰当的数据库设计方案。在工程实践中,很多数据库设计方案是由不当设计造成的,所以,在设计阶段,我们必须要考虑数据库设计问题。这里面包括逻辑数据库设计、物理数据库设计、物理数据库部署问题,分别就是本书第1~3章的内容。

正确的数据库物理部署和适应性配置策略,恰当的数据库访问设置和硬件资源的使用设定,是数据库优化运行的一个重要性能因素。这里主要涉及物理资源在操作系统层面的计算资源分配,存储空间使用的设置,内存资源的使用等问题。这些分别就是本书第4~6章的内容。

数据库可靠性和数据库性能往往会产生矛盾。那么,在Oracle中,我们如何考虑这个矛盾结合体呢?这是本书第7章试图要说明的内容。

对于Oracle来说,Oracle也许更适用于承载大规模数据,因为Oracle有着其他数据库平台所少有的大规模数据处理解决方案——多分区技术。本书第8章将向读者完整呈现Oracle数据库的表分区能力。

数据库设计中的一个重要内容是查询设计与索引配套。Oracle在处理查询时需要考量SQL查询的内容和对应数据库中表与索引的存在匹配关系,并因此由数据库优化器提交SQL执行计划。Oracle支持各种索引类型,那么我们如何使用这些索引类型,在什么情况下使用什么索引呢?这是本书第9章所试图描述的。

在数据库系统部署运行后,如何获得数据库运行性能状态,如何进行数据库运行中的资源使用分析,在分析时使用什么样的工具,以及这些工具返回信息的解读方法,这是本书第10~12章着重介绍的内容。这部分面向系统的运行监测和运维,试图解决我们在系统上线后“该做什么”的问题。

本书虽然是面向性能问题的,但是我也自知并不能解决所有问题。而且,本书中提到的技术观点和做法,可能在一些具体场景下适用,在其他一些场景下却并不适用,这点希望大家能够注意到。同时,作为本书作者,我在本书中没有写入任何所谓的“绝招、法宝”。近二十年从事数据库技术研究和实践的成功经验与失败教训告诉我,从来就不曾有绝招和法宝!能相信和依赖的,只有我们自己正确的系统观和工程实践上的科学精神,以及个人的勤奋和认真罢了!

恰在本书写作完成后,中国的IT业发生了一次不小的“地震”——华为正式进入IT领域,并成立IT产品线。鉴于对华为精神的敬仰,我接受了华为工作聘请,任职为华为IT架构师,进行数据库领域的产品架构设计和技术研发。我希望我的知识、经验,我的工作热情、潜能,能为华为在IT领域的拓展贡献自己的光和热。

同时,也祝本书的各位读者工作顺利、事业有成!文平第1章 综述:优化是一个系统工程

1.1 性能问题是一个系统工程

1.2 性能改进的工程方法

面向数据库系统性能的系统工程

本章将着力于阐述本书所倡导的一个基本技术观点——性能优化是要在全系统范围内考虑的一个系统工程。

众所周知,性能是涉及范围广泛的一个综合性问题。面对性能问题,有时候用户看到的仅仅是一个表象:“慢”!事实上,这个词太过含糊,其背后所涉及的问题可能包括:

❑哪台机器“慢”?

❑哪个业务“慢”?

❑什么时候“慢”?

❑什么操作“慢”?

❑谁操作时“慢”?

……

那么,我们就来尝试解决这个含糊的“慢”的问题。现在站到服务器边上,看看机架上纵横交错的连线,还有那如繁星般闪烁的群灯,然后问自己:“这个家伙到底哪里出了问题呢?”也许我们会考虑到如下一些方面:

❑可能是CPU过载了?一定有这可能!

❑是内存调度颠簸?一定有这可能!

❑网络传输出现瓶颈?一定有这可能!

❑磁盘系统访问延迟严重?一定有这可能!

❑I/O通道有硬件问题?一定有这可能!

❑内存泄露资源耗尽?一定有这可能!

❑系统出现Bug?一定有这可能!

❑业务数据量太大?一定有这可能!

❑用户连接太多了?一定有这可能!

❑用户正在执行某报表业务?一定有这可能!

❑用户正在执行备份?一定有这可能!

❑业务系统模块改变?一定有这可能!

❑中间件系统的问题?一定有这可能!

❑某些我们“尚不知道”的可能?一定有这可能!

对于上述的诸多可能,如果要尽述其细节,可能会列出数百种,甚至更多!假如我们能够列出一份排除清单,并逐一排除,相信很快就会发现一个基本的事实:我们已陷入了一个“问题”的海洋,并且难以自拔。

我写上述文字的目的不是想制造一种技术上的白色恐怖氛围,而是想说明一个技术观点:没有行之有效的方法,不掌握解决问题的规律,那么事倍功半是必然的!

也就是说,技术实现是有其规律的,这里冒昧地将科学泰斗钱学森的“系统工程”理论引用到性能优化这样的工程实践中来,全面系统地看待问题,找到方向,细粒度地解决问题,获得工程收益。1.1 性能问题是一个系统工程

如前所述,性能问题是一个系统工程。在这个工程中,不同的时间段具有不同的工作方向和工作内容,不同的技术方向又有不同的问题考量和实施纲要。在这里,我们将考虑它的不同阶段和各方面的问题。1.1.1 考虑性能问题的不同阶段

在实际操作中,我们会面临几种性能相关问题的工程场景:

❑系统未开发,尚处于系统架构之初。

❑系统开发中,已进入实质的设计阶段。

❑系统上线运行,已进入综合调试阶段。

❑系统上线后,已进入运维等日常管理阶段。

站在不同的工程场景中,我们在性能方面可以完成的工作也会相应有所不同。毫无疑问,最理想的系统性能设计要从应用设计阶段开始,并在整个系统开发周期中实现。待系统进入生产环境后还会继续调整,动态优化系统性能。

在初始的系统架构设计阶段,也许我们着重考虑的优化任务应包括以下内容:

❑服务器硬件上的选型。

❑系统可扩展性的设计。

❑系统容灾可行性的考虑。

当系统进入开发周期,并进入实质的设计阶段时,我们应该考虑以下内容:

❑系统的后台结构设计。

❑应用的前台模块与代码设计。

❑用户访问中的并发问题。

❑应用访问中的工作载荷要素。

当系统上线并经过测试开始运行时,我们可以完成的优化任务包含以下内容:

❑操作系统、数据库系统部署的合理性再研究。

❑后台数据库部署中的微观调整与实施。

❑部分应用代码的性能相关重构与库结构微调。

❑后台系统运维中的硬性任务安排设置。

❑应用部署结构的渐进性再调整。

待应用系统上线正式运行,已进入运维等日常管理阶段后,虽然我们可做的工作非常有限,但还是可以在以下事情上有所作为:

❑恰当组织数据存储结构,以优化性能。

❑恰当安排应用任务的执行区间,以优化性能。

❑恰当设置系统容灾结构,以避免对整体性能造成影响。

❑微观调整数据库对象(索引、物化视图等)的设计,以优化SQL。

不同的场景下,我们可以设置不同的性能优化方向,包括从宏观到微观,从整体到局部。1.1.2 考虑性能问题的不同方面

图1-1是我在性能优化工作中考虑问题所使用的综合导图。

图 1-1 面向数据库系统性能分析与设计的综合导图

假设图1-1所示的内容是正确且全面的(图1-1仅表述了我本人的技术观点,在一定程度上,作者认为该图是不全面甚至有技术缺陷的)。从图中可以看到,性能与“数据库服务器的方方面面(从硬件到系统、从平台到应用、从访问量到工作载荷等)均相关。

这就是解决性能问题很“困难”的根源所在。1.1.3 性能架构中的问题分类

既然不同的阶段、不同的方面都存在着性能问题,那么在系统设计阶段我们应该关注哪些性能问题呢?1.系统架构中的不同视角

何谓系统架构?那要看我们从哪个角度来看架构这个问题了。一般而言,如果从架构设计的角度来看,系统架构可能会有如下几种类型:

❑应用逻辑架构。此架构会从应用用户的角度来考虑业务功能的实现问题,目标是设计出能够满足业务需求、处理业务逻辑的应用系统。

❑应用开发架构。此架构会从应用开发人员的角度来考虑应用程序的框架架构、模块关系、流程编写、文档说明等,其目标是建立一个易于理解、开发、测试,能够满足应用逻辑架构的系统。

❑应用运行架构。此架构则会从应用运行的流程设计来考虑问题,包括系统的功能外观、界面友好程度、用户响应速度、用户并发支持、系统安全控制等方面的内容。

❑物理实现架构。此架构从系统的安装和部署等角度来考虑问题,比如如何在服务器上物理构建一套系统,使其能够满足性能指标、可用性指标、存储指标等。

❑数据流动架构。此架构以数据为内容,以流程为载体,把死板的业务数据表现为有意义的状态表现或内容分析。

注意 本书所描述的架构是站在后端服务器角度进行阐述的,包括面向应用部署、应用运行、物理实现等方面的架构内容,而非其他的技术领域。2.系统架构中的硬件问题

可以说,在所有的性能问题中,硬件问题是最好解决的,因为它只和经费相关!

随着硬件技术的进步,处理器、内存、磁盘驱动器的价格日趋走低,越来越多的用户在选择硬件时会挑选性能更好的。在某些情况下,添加新的CPU、扩展系统内存、添加更多的磁盘驱动器的确能够有效提高性能,而且效果是立竿见影的。

虽然增强硬件在大多数情况下能够起到短期缓解系统性能故障的作用,但当应用系统的数据量持续上涨,应用系统的访问工作量载荷不断攀升时,从硬件方面提升的性能往往也可能会被迅速消耗掉,导致在不久的将来仍然会面临同样的性能问题。那到时再次进行扩容吗?

例如下面的场景:对于一套Oracle RAC数据库集群(Oracle的并行集群,主要支持Oracle 9i、Oracle 10g、Oracle 11g及更高版本,支持集群节点的动态加入和删除),在一定程度上可以通过向RAC增加节点来使数据库服务能力得到“准线性”增强(也就是节点数上的扩容)。但这种“硬”性的扩容,其边际效果将是持续递减的,总有边际效用降低到0的时候。靠硬件的性能提升,其效果也是有限的。

很多情况下,硬件扩容并不能使系统性能得到显著改善,例如不合理的数据库设计、不恰当的SQL应用访问,都会使硬件的投入收效甚微。正因为如此,在用户进行硬件扩容前,判断硬件是否处于瓶颈状态是至关重要的。

那么又该如何判断硬件的性能情况呢?性能基准测试往往是服务器硬件厂商衡量服务器性能情况的技术指标,该测试是基于资源的使用和时间的消耗来实现的。但是很多工程上的实践告诉我们,这些测试可能并不能真正代表什么。也可以这么说,生产系统未来的性能指标和性能基准测试可能并无直接的、可靠的关系。在我作为责任技术顾问的一次现场优化项目中,硬件厂商提供了基准测试数据整整高于生产系统同类数据一倍的一套硬件,而实测结果却是“和以前没什么两样”(来自用户的评价)。

硬件性能只是系统性能组成中的一部分,上述案例已经说明了这一点。系统性能包括硬件、操作系统、数据库系统、应用系统、用户访问、工作载荷的整体表现。硬件性能只能代表局部的性能情况。

来看一个典型的案例:一套系统的tpc-C/tpm-C很高,但系统却运行得很慢,难道是硬件、软件选错了?用户很困惑。很多系统真就是如此!

大多数基准测试来自厂商,包括系统厂商(IBM、HP、Sun、EMC等)、数据库厂商(Oracle、Sybase等)、中间件厂商(Oracle、IBM等)。基准测试很多时候是一套服务器系统性价比的有效指标,事实上,对于某个具体的应用来说,基于具体的流程特征和业务压力的性能测试才有真正的意义。

IBM、HP等UNIX服务器厂商能够提供具有极高的可靠性和稳定性的产品。但即便如此,面向实际应用的场景测试仍是服务器选型的最好办法,因为你的应用是具有个性的。

看上去像是不可知论?其实不是,我想表达的观点是,硬件指标很重要,但千万不要太依赖这些参数,因为这些性能参数中恐怕只有很小的一部分会对你的系统有指导意义。3.系统可扩展性的配置

可扩展性是指系统能够处理更多工作载荷的能力。对于大多数系统来说,由于其承载的数据量将持续累积,同时随着用户对系统的熟悉和依赖,大多数数据库应用系统的总体压力持续增大。

对于一个可有效扩展的系统来说,工作载荷的逐渐增加将使系统资源的使用按照一个适当的比例同步增加,但不会超越工作载荷的增加比率。也就是说,工作载荷的增加不会导致系统载荷超量增加,这样才不会导致系统崩溃或挂起。

工作载荷的增加导致系统资源的使用增加反映在如下几个方面:

❑并发用户访问量增加时,系统并发性上的管理要求也会更高。

❑为支持多用户并发访问模式下数据的一致性和合理性,锁资源的相应性则会增加。

❑数据一致性的检查会带来工作载荷的增加。

❑要应对数据库系统的增量,操作系统工作载荷将会额外增加。

❑数据量增长后,用户单笔事务操作产生的工作量将会增加。

如果在工作载荷增加时系统不能对应地增加服务能力,而致使系统资源被快速地消耗掉,那这种系统就不具备可扩展性。不具备可扩展性的系统和应用往往具有下面的共性:

❑硬件资源被用尽,例如CPU长时间处于超高的繁忙程度,接近100%。

❑事务中存在的表扫描(table scan)类型,其大范围数据操作造成了大面积的磁盘I/O。

❑存在大量和过度的网络要求,导致网络拥塞。

❑对操作系统虚拟内存管理(VMM)调度的失衡,大量的页交换产生。

❑存在过度的系统进程分配,造成操作系统崩溃。

总体来说,时常会存在这样的误解——CPU数按倍数增加,服务器可扩展性也会按倍数同步增加。其实,这只是人们的一厢情愿,事实并非如此。对于服务器而言,其硬件系统CPU的增长也许会使其处理能力接近线性地增强,但事实上对于大多数的多处理器服务器来说,当处理能力达到某个极限时,额外的CPU所带来的性能增量将不再明显,更不能成比例地增加了。

在系统资源确定的情况下,应用系统设计者应根据用户数量、工作载荷来设计和实施相应的应用。在服务器的选型和配置上,经验值的重要性往往要大于技术指标。

站在整体的高度来看系统,决定系统可扩展性的要素如图1-2所示。

图 1-2 对系统可扩展性具有影响的诸要素

从图1-2可以看出,扩展性不仅和硬件相关,更和应用相关。在构建应用的开发阶段,系统的线性可扩展性特征应该作为重要指标之一。如果能把应用可扩展性与服务器引擎数(CPU)、内存量、I/O通道数直接关联(当然这是不可能做到的),则事情会简单得多。因为若果真如此,则增强服务器能力就可以了。所以,在应用开发中,要尽量扫除由于应用系统不当所造成的性能阻碍。

阻碍应用系统线性可扩展性的因素有很多,其中应用系统的设计和开发对可扩展性的影响最大,包括不良的应用设计与数据库设计,一般可以从如下几个方面考虑:

1)存储系统未以最佳I/O配置策略进行生产实施,造成了效率低下。

如果数量级小,I/O配置策略可能不存在问题。可如果由于大数据量造成了I/O压力,则有问题的存储通道配置造成的影响将会是严重的——在这种情况下,无论系统的内存怎样扩充、CPU个数怎样增加,都无法摆脱其所造成的影响。

2)在虚拟内存管理中,由于用户大量申请内存(如文件系统访问、数据库备份等文件操作任务),而导致整体服务器中内存交换过度。

无论内存有多大都有被申请用尽之时,不能尽快释放进程资源导致的内存过度消耗,会让任何服务器都无能为力。

3)糟糕的事务设计造成了锁等待和串行化事务问题。

尤其是面临锁的困境时,一个用户使用资源时另一个用户就需要等待,在数据库这种讲究事务一致性的系统中,我们会发现这种事务困境和服务器的配置高低无关,同时这种问题随着用户访问量的增多会愈发严重。

4)不良的数据库设计造成执行代价昂贵的SQL。

有些SQL不能拥有好的执行算法和访问路径(这称为SQL执行计划)。在数据量增大的情况下,其造成的CPU压力(排序等)、I/O压力(磁盘吞吐)、缓存压力(数据的缓存化)、网络压力会呈几何递增,这也就说明了为什么很多系统的性能问题本质上都是SQL造成的。

5)不良的SQL和不当的索引设计导致应用系统I/O总量上的巨大开销。

SQL执行计划和数据库E-R结构有直接关系。不良的SQL既可以理解成是编写差劲的SQL,也可以理解成是后台设计欠佳的数据库对象(前台SQL与后台数据库对象之间是“先有鸡还是先有蛋”的关系)。不良SQL造成的恶果之一便是使应用系统在I/O总量上产生巨大开销,而这就造成了服务器存储模块的瓶颈效应。

6)在生产环境中应用SQL实际执行的计划与预先设计的计划严重偏离。

可能某些SQL在设计之初拟定的执行计划是一回事,但在运行状态下其实际执行的计划又是另一回事。计划的偏离导致了不佳的SQL效率。当然,这件事情的另一个后果是,不佳的SQL可能在某些情况下会有上好的性能表现。适时而动,是功能强大的数据库所必有的特征。

综上所述,系统的可扩展性,部分表现为硬件的处理能力,部分表现为应用系统的可扩展性问题。4.系统性能设计中的关键

在当今以云计算为主流的应用开发体系结构中,多层结构俨然是事实上的主流。理想的情况下,客户端仅仅是一个"Pad"、一部智能手机,甚至是桌面云的使用者。在这种情况下,数据库类应用系统将横跨数据库节点(提供数据服务)、中间层应用节点(提供应用逻辑服务)、客户端节点(提供界面表现服务),以及客户端应用。横跨的方式就是网络的多层结构。

在图1-3所示的应用结构中,数据库服务器、中间件、客户应用、多层应用协同工作,构成了一套完整的应用系统。

图 1-3 完整的应用系统往往跨越多个层次,表象为多层的应用结构

性能问题显然综合了各个层面的问题。在上述的多层(多节点)环境中,各节点间效率均衡的系统就是好的系统。就像水管一样,从头到尾半径一致的水管一定比粗细不均的水管效率高,因为最细的部位决定了这根水管的流量。各层次(节点)间载荷均衡是我们追求的目标,也就是说,没有瓶颈的系统就是好的系统。

从硬件的角度看,主要有以下四个方面决定了效率:

❑CPU:配置CPU使服务器性能达到一定的标准,它是我们常见和衡量服务器的指标。

❑内存:数据库和应用服务器要求有大的内存结构缓存数据,以减缓I/O压力。

❑I/O子系统:每一分钟数据库和应用服务器都会在磁盘子系统(本地磁盘或高性能磁盘阵列)上执行成千上万的I/O,I/O往往是大多数系统的瓶颈所在。

❑网络:具有一定带宽和速率的网络通信环境。

从数据库系统的角度看,数据库系统的运行会产生对操作系统功能的申请和使用,以及处理用户请求时的内部操作。数据库系统主要有如下几方面影响着未来的性能:

❑计算资源的使用:Oracle作为资源的使用者,以一组进程(Oracle后台进程和用户会话进程)的形式申请CPU的时间片分配。如果这些进程不能得到恰当的CPU处理能力,或者在得到CPU处理能力后,又不能将计算时间有效地用于数据处理(例如高的锁等待时钟周期),则数据库性能将会因此而受损。尽管资源的使用方式与应用系统有着直接的关联关系,高的CPU处理能力无疑在任何时候都是受欢迎的。

❑内存资源的使用:数据库类应用的特点就是要申请大量的内存结构以用于数据的缓存和进程间的通信服务。如果没有大内存结构的支持,缓存数据的能力将会受限,代价就是I/O压力的增加。我们知道,内存的数据处理速度和外存(磁盘)的处理速度有很大的差别(其效率比率在4位数以上),内存申请的重要性也就不言自明了。

❑栓、锁的管理:要使用系统资源,就需要拥有使用资源的许可,这称为栓(资源锁)。使用数据资源,就要使用数据行上的锁,这称为锁。栓、锁都是Oracle实现系统并发性访问的约束和管理机制。好在Oracle已将栓、锁的管理完全自动化,无须管理员再配置。

❑数据存储和I/O的使用:无论如何缓存数据,数据最终都会存储到磁盘子系统上,或者会执行反向读操作。这意味着大量I/O的并发执行。从表象上看,I/O往往是系统的瓶颈所在,可实际上,也许是内存的瓶颈,也许是不当SQL造成的非有效性I/O。

❑用户连接管理:Oracle是一种典型的多用户数据库系统,用户连接后,即可以以独立的会话模式执行数据库访问。单机下会话的管理、维护,在并行RAC集群下的会话管理、维护,会话对系统资源的使用和开销,会话模式的选择,都是架构中事关性能而必须考虑的问题。

❑网络通信:既然是客户/服务器应用,网络的使用也就是必然的了。Oracle通过网络接收用户请求,并将结果反馈给用户。

从应用系统角度来看,应用系统可以拆分为若干个功能模块。模块化拆分和部署不仅带来松耦合的益处,也往往能够带来结构上的优化。大多数应用可以拆分为如下三个组成部分:(1)用户接口(UI)

用户界面表现,用于用户数据输入、数据校验、业务逻辑调用等操作。这部分往往包括以下两方面的内容:

❑定义简洁、有效的工作界面。不复杂、不过度渲染是高效系统的一个基本特征。实际上,对于那些具有丰富功能的(应用系统)用户界面,用户最常用的99%可能是最基本的功能。那些复杂的功能用户可能半年或一年都用不到一次。为了百分之一的使用可能性,而付出百分之百的编程代价和运行性能代价,值得吗?(想想手机上那些丰富的按钮和功能,除了电话、短信、游戏之外,其他功能我们又用过多少呢?)

❑定义简单、明了的界面操作流程。功能不要太多,或者采用较为严格的预定义业务逻辑,进而简化流程,提高运行效率和减少编码量。这里的部分原因同上。(2)中间件业务逻辑

实现业务流程和业务目标的过程化计算部分,如执行某种算法、进行数据库访问、生成用户接口等。这部分往往包括以下内容:

❑编写各种组件,完成某种业务功能。

❑执行数据库操作,完成数据的存储和管理操作。这里需要考虑的问题是,是在数据库端处理数据还是在中间件端处理数据。从减少网络通信和会话维护的角度来讲,数据库端的集中处理有很大的益处。但站在中间件的角度,也许有些应用更适合在中间件端处理数据,如何选择呢?这的确是一个问题。

❑管理和维护用户到中间件的连接以及中间件到数据库的连接,并对这些连接会话进行维护。这里需要关注的是数据库连接效率,因为这里涉及中间件运行状态下的设置问题:数据库连接池的问题。(3)数据库业务逻辑

实现业务流程和业务目标的数据库计算部分,如把数据存储到Oracle数据库的表中、根据条件修改数据库数据等。在数据库部分,大多数的数据管理任务是由数据库自动完成的,这些任务包括:

❑数据库的连接管理。

❑SQL执行计划的管理。

❑SQL执行中游标的共享管理。

❑数据库会话状态信息管理。

❑用户操作在资源使用方面的均衡。

❑异步任务下的执行队列管理。

❑事务管理,这本身就是数据库服务器的基本功能。

❑数据管理,使用锁和DML语句操纵数据。

❑性能管理,依据索引和缓存策略优化SQL执行路径。

❑可用性管理,通过日志保证系统损坏情况下的数据恢复。

另外一些任务则需要设计者和编程人员共同完成,比如数据库的对应性设置与优化,其中包括:

❑Oracle中的数据存储方案制定与优化,如表空间优化等。

❑Oracle中对数据缓存化方面的设定与优化,如SGA(内存)设定等。

❑Oracle中用户对系统资源的使用限定,如Shell limit等操作系统限定。

❑Oracle用户连接所使用资源的限定,如用户连接量限定等。

架构顺畅的系统往往是决定系统效率的根本因素和必要条件。鉴于系统架构的复杂程度,绝大多数时候并没有什么具体的“规则”或“约定”来确定一件事情该怎么做,至多是一些“最佳实践”类的引导。因此,结构方案的设计在很大程度上要采用多重迭代的方法来逼近。5.多次迭代优化系统结构

每个系统都有其个性和特定需求。“万金油”类的系统架构是不存在的。一种成熟的设计方法是使用多次迭代的方法来渐进性优化。在此方法中需重复考虑如下问题,并依据答案调整体系结构。

问题一:系统目前和未来将支持的用户数

对于少量用户访问的系统或单用户系统来说,由于它们少有争抢资源的现象,在响应时间上进行优化是可能的。

对于中等或有大量用户访问的系统(几千用户访问量的范围内)来说,个体用户的访问需要与其他进程共享系统资源,这些资源包括栓、锁等,因此单个用户的反应时间一定会受到影响,其响应时间上的要求也就需要适当降低一些。相对于数据完整性,单个用户的响应性能就不再优先了。

如果是大用户量的访问模式,例如在Internet上的数据库访问,由于难以(无法)预计某个时刻的用户连接和数据访问量(我们想想2008年北京奥运会的网络预约订票系统、2012年铁道部的网络客票订票系统),这时必须依赖某种缓冲机制来防止服务器资源在尖峰载荷下被耗尽。这种情况下,可以采用均衡负载的方式来降低服务器压力(构建Oracle RAC集群、构建Golden Gate或Data Guard同步复制系统),同时使用中间件方式将用户访问分层(例如构建WebLogic集群),以保护系统在资源强力消耗的情况下仍不被挂起。

问题二:用户的界面模式

从传统来看,应用系统一般都经历了主机系统(20世纪80年代)、客户/服务器模式系统(20世纪90年代初开始)、Web模式系统(21世纪开始)几大阶段。目前,基于Web模式的应用系统比较普遍,而基于云计算的轻量级客户端应用现在已经开始出现。

这几类系统模式相比而言各有各的特点和优势。就拿Web多层应用模式来说,目前一种较为主流的架构方式就是以Oracle、Sybase等为数据库服务器,以WebLogic、JBoss、WebSphare等为中间件服务器,以浏览器为客户端。

在选择合适的用户界面模式时,对于是否采用新颖的(类似于云计算)技术,进行恰当的技术验证是必需的。

问题三:应用系统各层次(节点)的物理分布

这里涉及物理站点和相关的网络配置问题。网络环境为我们提供了在应用系统、数据库系统之间进行数据传输过程调用的能力。为实现业务逻辑,应用系统和数据库之间的交互频率可能会很高,也可能会很低。从另一方面来看,网络连接间接决定了业务逻辑的实现效率。

例如,我们可以在应用界面设计中使用逐字提示的做法,来对用户数据输入的内容进行逐字逐句的提示(这可能需要不断地进行数据库访问,以确认其正确性),但这同时会意味着较高的网络开销和数据库访问工作量。

与这种做法完全相反的另一个极端设计是,用户在其界面上输入的内容在数据提交前不进行任何数据校验,也不进行数据库访问,直到用户确认和提交数据。这会大大降低网络流量和服务器工作载荷。但与此对应的是,用户界面是不太友好的。在这样的得失选择中,可能我们需要先确定某种倾向性。

问题四:用户访问的数据量和动态数据量分布

用户进行数据访问的过程中,数据量的大小及数据的分布状态将直接影响到数据库的操作效率。这就要求我们在逻辑设计方面和物理方面提供相应的对策。其中,数据库表的设计、索引的设置是最受影响的元素。

一般而言,随着使用时间的增长,数据库中数据空间的占用会日趋庞大。如何使用户访问的响应时间尽可能少受数据量的影响,或者说,如何通过削减数据量来减少对数据访问的影响,是我们在设计时需要考虑的问题。例如,我们通常在进行数据库实体关系设计时,会对预期的大表采用垂直分割技术或水平分割技术(在使用PostgreSQL、MySQL等数据库时),或者直接使用表的分区化技术(如Oracle、DB2等支持分区的系统),从而作为针对数据量增长要素的应对预案。

问题五:用户对响应时间的要求

除非是一些对时间极其敏感的数据库应用系统(如PLC工业控制系统),一般我们可以考虑拿用户响应时间来换取系统可靠性。例如,增加数据库日志成员数、增强节点容灾能力等。

问题六:应用系统7×24小时的运行需求

除非是必需的,否则7×24小时的运行需求会造成系统整体造价直接提升,同时也会为系统运行带来额外的工作压力。因为高可用方案的设置(如硬件级镜像、文件级镜像、同步复制等手段)往往也降低了系统的运行性能。另外,并行访问方案的设置(Oracle RAC等)会明显增加系统的复杂度。

问题七:数据库容量的发展趋势

对于一个海量存储的数据库系统来说,硬件的功能指标十分重要,往往一组高效的小型机集群(如AIX UNIX)是必不可少的。同时,这套服务器的CPU数、内存数、I/O磁盘子系统都将是关键要素。

综合考虑上述问题,并参考类似系统的工程实践,才能得到一个接近优化的应用系统服务器结构。6.应用结构设计中的优化

在应用设计中,尽量采用下面的原则来提高数据库的整体性能:

❑简化应用设计,不设计与功能主体不相关的模块,特定的需求应考虑在特定的模块中实现。

❑在数据建模中,原则是简单、明了,过于复杂的数据关系将会导致开发上的困难和性能上的让步。

❑表的关系设计,很有可能需要在范式层面上进行让步与妥协,也就是数据库要进行恰当的非规范化设计。

❑索引的设计,要充分认识到索引的两面性,不能太少,也不能太多。那究竟多少合适呢?没有答案,只能根据实际情况来处理。

从工程上讲,好的设计会带来好的可靠性、可维护性。数据库应用系统的应用构架也同样如此。充分的设计会让后续工作顺利进行,从而开发出高效、实用的应用系统;不充分的设计带来的不仅是开发阶段的痛苦和运行阶段的低效,还会导致后续需要不断地进行系统优化和应用优化,例如,可能会出现下面的几种情形:

❑数据库表的设计可能充分地体现了业务的逻辑,具有很高的范式结构和关联关系,可是,没有人能看得懂。

❑应用中的SQL语句在编写中充满了技巧——叠加的、嵌套的、扫描许多表的,但是,这些优美的SQL语句有时并不能从数据库优化器中得到合适的执行计划,SQL执行导致了大量I/O操作和事件等待,如果是这样,那么这条SQL语句也就一般了。

❑SQL A需要一个索引,SQL B需要另一个索引,这两个索引的内容也许相互包含,这时,索引的重新规划显然是最好的选择。

❑用户通过应用系统提交事务,但操作请求不能在有效的时间内得到响应。是不是应用界面的设计有问题?是太过花哨,还是数据库事务安排不当?

❑应用中系统功能的调用经过了若干层次的调用实现,这样的应用逻辑拆分、模块分层是否有效率问题?

目前并没有一种适用于所有情况的数据库类应用设计规范,作为本书作者,我同样无法提出一种具有广泛意义的应用框架。之所以在这里编写这样一节,是因为在实际的应用系统设计和实施中,我们时常会看到一些由于底层设计不当而造成上层应用低效的场景。设计不当带来的性能问题往往是不可优化的、难以扩展的,会为后期的使用带来无尽的麻烦。7.数据库建模阶段的优化

数据库应用的特点之一是其建模过程具有明显的两部分:应用系统的前端建模和后端数据库建模。这里所谓的后端数据库建模,就是根据用户的项目需求,抽象和模型化出应用数据库的实体对象——以表(实体)为代表的数据库模型。

数据库建模也分为两个阶段:

❑逻辑模型的建立:根据用户需求推演出来的数据库实体关系图。在制作实体关系图时,必要的范式是要求一定要达到的,如第三范式。

❑物理模型的建立:根据应用逻辑模型,实施到某个具体数据库平台(如Oracle)的数据库物理结构上,该结构将由具体的表、表的约束、表间的关系构成。这个物理模型将服务于某个具体应用,出于特定开发的考虑,我们往往会在物理模型上进行规范化的反向操作——反规范化,从而实现设计时的针对性优化。设计完成的数据库物理模型一般会如图1-4所示。

图 1-4 数据库模型

在物理模型建立后,将这个模型构建到一台具体的物理服务器(例如一台挂接DS4700存储设备的IBM p570 AIX服务器)上,这称为数据库的物理部署。在这个阶段,适应性部署极为重要,因为这涉及服务器计算资源的使用、存储资源的使用等。

数据库模型的建立是应用整体设计的后台基础,其实现的结果相当于建筑工程中的地基(底层结构)。在我们设计的数据库实体中,那些被频繁访问的实体(如表和视图)往往需要给予较多的关注,因为它们可能是决定日后应用系统性能相关问题的主要方面。例如,财务系统中的“分类账表”、“票据表”,销售系统中“库存表”、“销售凭证表”等。这些表在应用的使用过程中会被大量涉及,它们是数据建模阶段的主要矛盾。其他的数据库实体在性能上的影响则相对较小,所以可以给予较少的关注。当然,这里说的前提是,在有限的开发时间、有限的开发资源、可以满足业务逻辑实现的情况下。

数据库表的设计很大程度上既是技术也是艺术,可以堪称为一种“妥协”的艺术性技术。数据库表的设计可以倾向于性能方面,使其便于优化,也可以倾向于数据完整性方面。在若干种相对矛盾的思维组合中,妥协往往是解决问题的可行方法。为了使数据库能够在未来可预见的工作载荷条件下提供稳定的性能,数据库表的设计至少应满足第三范式。同时,还要兼顾性能方面的考虑,所以适当的非规范化操作必不可少,甚至更为重要。

为什么说这是妥协的艺术性技术呢?表的规范化设计可使数据库实体的数据冗余度降低,而非规范化设计则是以提高冗余为代价的(如添加冗余列、预连接列、存储统计值等方法)。非规范化设计会降低数据库在接受SQL请求时的CPU计算量,但一般会增加数据存储压力、I/O访问压力。究竟孰是孰非,应就事论事!

同样,没有一种强制性的设计规范要求我们如何进行设计,也没有一种放之四海而皆准的标准供我们采纳。至于如何设计数据库模型,也许本书后面相关的章节能够说明这个问题。8.索引设计中的效率因素

众所周知,索引在SQL执行计划的生成中占有重要地位。在表结构及数据量相同的条件下,给表设计出不同的索引结构,其结果是导致相同的SQL具有了不同的执行路径。如图1-5所示,就是在某些情况下由于索引对象的存在,SQL将使用索引来作为SQL的扫描路径,并认为该方法是优化的。

图 1-5 表、索引的匹配关系将影响到SQL的执行计划

索引设计往往也是一个多重迭代的过程,在对其进行设计时要基于应用系统中访问这个表的大多数SQL语句来考虑。同时,在数据库表上定义索引后,程序员应参考索引的设计情况来编写恰当的SQL语句。

这看上去很让人困惑:究竟是先有索引,还是先有SQL?如果你不明白这个问题,那么参考一下这个问题吧:是先有蛋,还是先有鸡?这两个问题都很难回答,但显然它们的答案是相同的。

但在系统设计之初,数据库还是可以按照如下的一般性规则来预先定义部分索引:

❑首先,表一般会有其主键列,该列用来维护表中数据行的唯一性。理应对这一列(或联合主键列)创建一个索引。在Oracle中,设定某个列为主键则会自动为其匹配索引。

❑其次,在可能的情况下,尽量汇总与这个表相关的SQL操作,区分这些SQL语句的使用频繁程度,选出若干使用频率高的SQL作为代表,且以此为依据设计索引。

❑再次,在开发过程中使用的测试数据库要和运行状态下数据库的数据量接近,最好在预计数据量后,在开发系统中加载稍微有些过量的数据。

❑最后,测试典型的SQL语句,分析其查询计划,并配置对应的若干索引来优化其执行计划和执行效率。9.SQL执行效率的预评估

在大多数情况下,一套应用系统的效率问题在表象上都指向了I/O问题。I/O效率低下的确是可能的原因之一,但除了存储设备在硬件、操作系统方面的约束原因之外,应用系统数据库设计及数据库操作的SQL语句也可能是产生I/O瓶颈问题的根本性原因。试想如果我们想从北京到天津,但我们偏偏要从郑州绕一圈过去,这时候开什么车已经不重要了,因为这时路远是主要矛盾。

因此,在应用系统开发之初,SQL程序员除了要了解业务需求以外,还必须关注应用中SQL的效率可用性。SQL的效率可用性在开发中往往可以反映为如下几个技术层面的运用:

❑恰当的数据库连接机制。

❑高效的游标使用和管理。

❑SQL执行中的硬解析、软解析。

❑无论哪种解析,其计划是优化的。

客户应用连接数据库时,数据库将维护多用户访问下的会话管理、堆栈结构、游标信息等,如图1-6所示。

图 1-6 Oracle中的客户连接和SQL执行

Oracle客户连接是以进程方式体现在操作系统中的,而在Oracle中则表现为一个个的服务器进程。每个服务器进程都有其独立的堆栈结构、会话数据信息、游标信息、数据排序区域。不仅如此,所有的服务器进程会共享Oracle SGA,在SQL执行过程中,所有的SQL会在SGA中的Library Cache(库缓存)内存结构中被缓存,同时被缓存的还有该SQL对应的可执行伪代码(Executing Plan:具体的执行计划)。

客户连接本身就是一个资源消耗型工作,从应用开发的角度来讲,数据库同时连接的用户数应尽可能地少,这样才会降低服务器的压力。同时,对于某个具体的用户连接进程来说,其数据库连接最好在应用启动时完成,而不是在应用进行中不断地连接、断开、再连接。推而广之,在一套多层结构的应用里,中间件层(应用服务器层)提供的“数据库连接池”(connection pool功能)就是用于实现这个目的的,它可保证不会出现频繁的数据库连接及断开操作。

所以,中间件服务器的数据库连接缓存池可以起到连接缓冲的作用,这是一种在互联网下避免数据库连接冲击载荷的重要技术手段。

站在SQL的角度,最大限度地减少SQL执行过程中的语法分析活动,是SQL优化的一个准则。我们知道,在Oracle执行SQL语句时,语法分析是解释并执行SQL语句的首要过程,包括分析SQL句法、检查执行权限、生成执行计划、装载共享结构等。语法分析结束后,数据库优化器将确定其执行计划,并将其编译成伪代码后提交Oracle内核执行。语法分析有两种不同类型的分析方式和操作步骤:硬解析和软解析。

如果数据库内核系统发现一个SQL语句是首次被提交,没有在共享池中找到该SQL的执行痕迹,则数据库不得不对这条语句执行硬解析,包括SQL语法分析、确定执行计划、编译执行等过程。这种解析方式必然会造成对资源的大量使用。

软解析与硬解析不同。如果一个SQL语句被提交给数据库,而这条语句(SQL及其对应的SQL执行计划Execution Plan)可以在一个称为库缓存(Library Cache)的共享池中找到,那这条SQL语句可能就不必再次硬解析了,原因是不久以前(若干时间内,可能是几分钟或几小时内)某个用户曾经执行过这条SQL语句。如果这条SQL语句已被缓存到库缓存中(共享),其语法分析和编译结果可以被后续的用户所使用,从而避免再次被解析。

显然,这有益于降低系统资源的使用,提高整体性能。有一点需要说明,虽然这种情况下的硬解析过程省略了,但SQL的句法分析和用户执行权限检查仍然存在,因此,软解析仍然会部分消耗系统资源。这是SQL执行的必然代价。

从性能上看,一条SQL在经历硬解析后,如果再次被执行,则执行应为软解析方式。这就要求SQL在编程中具有一致性。因此,在设计过程中最好能够制定某种编程规范。我曾在北京的一家著名数据处理公司看到过其内部编制的SQL规范,摘取其中几条供大家参考,如下所示:

对于表名的使用

规则一:必须大写

规则二:多表连接查询,表名按升序自然排列,不能含有多余的空格

规则三:优先使用预定义视图,而非在线视图(inline view)或子查询

规则四:使用在线视图(inline view)或子查询时,请先行提交需求

……

对于列名的使用

规则一:必须小写

规则二:列的出现顺序严格按照其在表中的位置按顺序出现,不能含有多余空格

……

SQL语句所使用的变量

规则一:使用绑定变量

规则二:变量的数据类型定义需采用%type

……

SQL模块化的要求

规则一:基础模块建议在存储过程、函数中完成

规则二:基础模块群建议在包中完成

SQL语句的注释说明

……

在这些规范中,可看到有关规范化的两个举措:

❑SQL的规范化编写

❑SQL的可重用性侧重

程序员可通过编写尽量标准且通用的SQL语句,来适应这种硬解析及软解析执行机制,避免系统中出现大量“陌生”的SQL语句,进而减少对CPU资源的申请(次数和时间),这不也是优化的一部分吗?

为了保证绝大多数SQL语句可以在共享池中共享,程序代码中的SQL应尽可能使用绑定变量,这样可以避免SQL在执行中因变量的不同,而导致数据库优化器对SQL语义曲解,进而导致硬解析出现。

当然,绑定变量的使用也是典型的双刃剑,但大多数情况下其效果是好的。不过有一点要提醒的是,在程序设计阶段就进行约定非常重要。SQL编程规范要争取在设计阶段完成。10.数据库视图的使用评估

视图可以起到简化应用设计、提高开发速度的作用,因此程序员大多有使用视图的倾向和意愿。这原本没有问题——简单的视图定义能屏蔽复杂的数据查询结构。

然而,我们也应该意识到视图在提供简洁数据表述的同时,还造成了SQL在执行上的复杂化,并且某些极端的视图甚至可能会导致系统在资源使用上的尖峰载荷。一种常见的开发失误是:程序员使用了某定义和视图,而该视图又引用了其他的若干视图。如图1-7所示就是这样的结构——在视图上创建视图,形成了由多层视图构成的金字塔结构。

图 1-7 多层视图的结构

Oracle在运行状态下调用视图时会将视图还原为SQL语句。显然,最终可能会导致处于顶层的视图在还原为SQL语法后十分复杂,其操作范围会涉及若干表。这对于Oracle来说是个难题——多表参与SQL操作提升了SQL复杂度,Oracle优化器并不一定能为非常复杂的SQL计算出优化的执行路径,因为优化器不会用几分钟时间去设计成百上千种执行计划,然后再选择最佳的方案执行。

所以,视图虽好,但在初始设计时,应考虑避免上述的极端情况。11.开发阶段应考虑的问题

在数据库类应用的开发阶段,我们应该关注哪些问题呢?

在应用开发过程中,尽管开发工具可能会不同,而且编程语言也存在差异,但一般就效率而言,下面的规则是具有一定的普遍性的。(1)应用界面设计

基于Web页面的应用和基于桌面(如Windows)环境的应用,在性能问题上有相同之处。在Web环境下,由于有大量的HTML脚本和Java对象在客户与服务器间传递,因此,减少用户的响应式操作进而减少网络传输,是多层应用模式的一个显著要求。(2)业务逻辑设计

对于业务逻辑的实现而言,Java和PL/SQL都是不错的解释型执行语言,它们独立于平台,相对独立,易于升级和迁移,也易于编写和理解。业务逻辑可以存在于客户机上,并以客户应用的模式存在;也可以存在于专门的应用服务器(Oracle Cache Fusion、Sybase EAServer等)上,并以组件的形式存在;还可以存在于Oracle数据库中,以存储过程、函数、包与包体的形式存在。一般而言,处于中间位置的应用服务器是业务逻辑部署的最佳位置。(3)用户请求和资源分配

在大多数情况下,数据库服务器对SQL执行过程中的游标管理是不需要人为介入的。但在第四代开发环境下(如著名的PowerBuilder、Delphi等),高度的开发智能化也带来了潜在的低效问题。例如用户连接管理低效、SQL游标使用笨拙等。拿Sybase PowerBuilder引以为豪的数据窗口来说,数据窗口生成的SQL很多时候执行效率欠佳,虽然从开发速度来讲,4GL的开发速度是无与伦比的。(4)数据管理和事务

数据管理和事务是数据库的关键任务,不受编程语言的影响。如果能将业务逻辑直接实现于数据库中,并使其以存储过程、函数等形式存在,则会减少客户端到服务器端的网络通信量,从而优化应用的网络通信层。(5)业务逻辑开发

我们需要使用过程性语言(如C、C++、Java、PowerBuilder等)编写流程化的业务逻辑,并使用SQL进行数据访问(查询、更新数据)。当流程和数据处理结合在一起时,流程中就会出现数据库操作。注意,这里面可能存在性能陷阱——当SQL参与业务中的循环类操作时,可能会导致数据库访问量显著增加。(6)测试系统数据量

数据库中数据的“量”这一要素确实难以评估,尤其是表中的可变长类型数据在行宽、空间占用方面的评估。同时“量”的增长也是很难估计的,因为这取决于用户的业务量。但总有规律可言,而且最好找到这个规律,并将其反映到开发环境的样本数据中。样本数据越趋向于真实,则程序员、数据库管理员对其增长规律的掌握也就越真实,程序员在考虑SQL和索引配比关系时也就越准确。Oracle 11g提供了工作载荷重放的能力,这有助于测试环境的真实化使用。(7)数据量增长的速率

数据量增长不仅是数据库管理员应涉及的关注点,同时它也是程序员研究性能问题的一项技术指标。应用系统中SQL执行的速度变化往往是数据库空间占用的变迁导致的,不一定总是SQL的问题,在这种情况下把责任归咎于SQL是不恰当的。有时,数据库中会存在一些空间增长异常的表和索引,所以监控其空间分配,防止其成为性能恶化的根源对系统性能分析来说至关重要。因为SQL在执行计划确定时,数据量是考量执行路径的关键依据。(8)数据存储的离散化

SQL性能不佳可能是由于数据增长对系统性能造成了负面影响,但同时也可能是由于表数据、索引数据的离散化导致SQL最终的I/O操作增加而造成的。当数据增长时,表中数据占用的数据块将增加,索引中的索引数据块将分裂。当表中数据被删除、更新时,表所占用的数据块可能因数据减少而变成空块(半空块),索引的叶节点数据也会变为空。因此,即便总的数据量保持稳定,但由于存储离散(空洞化),SQL仍然具有变慢的可能,在这种情况下将责任归咎于SQL同样也是不恰当的。1.2 性能改进的工程方法

无论是操作系统,还是Oracle数据库系统,都可以提供用于系统性能分析的工具和方法,并在合适的改进策略下,协助我们查明系统性能问题的所在,帮助我们识别性能瓶颈并将其定位。1.2.1 不要希望一步到位!

如前所述,性能问题是一个综合问题,性能的表象是操作系统、数据库系统、存储系统、网络系统、应用系统共同工作的集中状态。就像是一个数学方程,变量成百上千,如何求解?只能逐一求证。

常见的性能情况可能是这样的:性能瓶颈可能散布在系统中的多处。定位并调整了某一个,然后又出现了另一个。而且从综合调整的结果来看,系统性能可能并未发生实质上的改变。甚至有时系统调整后,导致了另一种更低性能的状态。

这就是我想说的关于性能调整的方法论——在解决性能问题时,我们必须要有心理准备和成果预期,想要一步到位是不太可能的,渐进式的性能改进、迭代式的渐变过程是必需的途径。

在调整性能时,我们更应放弃一步到位的心态,找到正确的方向,逐项调整,这样应用才可能调整到适当状态。

性能问题一般会表现为两个方面的内容:一方面为系统缺乏吞吐能力,另一方面为系统缺乏快速的响应时间。基本上,出现性能问题时两种表象皆有。问题的根源既可能存在于应用系统的某个功能模块上,也有可能是整个系统的不匹配。

难道性能问题具有不可知性?不是!在深入研究系统问题之前,最好能首先明确问题的方向所在。在这个问题上,应用系统的用户往往是最有发言权的。也就是说,在深入到任何数据库或操作系统性能统计数据前,最好能先去聆听用户对于性能问题的整体描述,定位问题的表象,进而评估问题的方向,最后再参照统计数据确定优化工作的工程方案。

这就是抓主要矛盾的工程方法。通过用户的反馈,我们先行定位问题的主要方面,了解性能的关键指标。例如,一个报表在300秒之后才能获得、另一个查询一般需要2分钟、在某时候执行了某操作后系统就变得很慢,等等。了解这些的好处是,模糊的优化目标可能会变得更清晰,而性能数据的海量统计也可以用来协助支撑工作目标的定位。这样,我们就开始了性能调整迭代的第一个循环。

理想情况下,Oracle性能优化的迭代尝试是一个循环上升的尝试过程。通过若干的迭代,最终达到性能目标。但是有一点需要强调的是:整个过程同时也是一个具有高度交互性的过程,可能存在一些测试和实验,这本身可能会对系统的运行性能造成影响,甚至某些操作过程会导致性能显著下降。因此,进行优化需要掌握综合性的知识并具有足够的经验,同时,要有“胆大心细、遇事不慌”的阿庆嫂素质。

优化失败是我们“一定”会遇到的!我在写这段文字的时候,想到的是我最为失败的一个案例。在某个优化项目的数据分析完成后,我提出了表索引调整的工作建议,并在测试系统中评审通过。可当在

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载