1.1 性能目标
在探讨数据库优化之前,我们首先要准确地理解性能问题,请看以下两种情况。
第一种情况,如图1-1所示,这是一张水管图,左边的箭头代表水量,其宽度代表水量的大小,可以看出,在水流经过水管的过程中,由于水管的宽度无法满足水流的需求,必定会产生性能问题。
图1-1 性能瓶颈(1)
但是如果水管没有任何变动,水量却减小很多,就会出现第二种情况,如图1-2所示。在这种情况下,虽然水管的结构依旧不能称之为良好,但已经足够满足水量的需求。
图1-2 性能瓶颈(2)
相信很多人都非常熟悉以下场景,业务系统在测试阶段或刚上线时往往一帆风顺,但上线后随着时间的推移,就会频繁出现各种性能问题。就像大家熟知的铁道部订票系统,平时运行正常,一旦遇到春节、国庆节等业务高峰期,能够登录其订票官网并成功订票就会成为用户的奢望。抑或一个系统平时运行良好,但是在开发人员或者运维人员进行了某些操作后,性能就会急剧下降。
在面对数据库性能问题时,我们首先需要明确调优的根本目标,一定要把注意力放在真正导致整体运行时间变慢的环节,并且不要通过一些片面的信息就妄下结论。
套用在电影《功夫》中,反派第一高手火云邪神的名言“天下武功,无坚不摧,唯快不破”,武侠世界中一秒钟有可能决定一个人的生死,而在整个IT系统运行中,响应时间的多少也成为评判一个系统性能好坏的重要标准之一。此外,系统的资源是有限的,但是用户的需求是无限的。在有限的资源条件下,让应用程序的运行尽可能地达到最快速度就成为DBA和系统运维人员最需攻克的难题。数据库调优就是在这种前提下孕育而生的,其根本目的就是让应用程序在系统中达到让用户满意的效率。一个系统性能的好坏,完全取决于这个系统在高峰时期的响应时间及吞吐量。下面列举了响应时间和吞吐量的定义及一些简单的例子。
1.1.1 响应时间
响应时间是指从应用程序提交请求到返回该请求之间的时间,其中包括:
● 应用连接到数据库所花费的时间;
● 数据库查询所花费的时间;
● 等待的时间;
● 将字符回显到终端的时间等。
在一个与应用集成的数据库系统中,响应时间又包含应用程序响应时间与数据库响应时间,由于数据库与操作系统密不可分,有时,响应时间过长的可能原因是操作系统或者存储等底层硬件的配置参数设置不当,或是由于设计不当导致整个系统的性能出现问题。当数据库出现性能问题时,我们不应该急于下定论或者急于从数据库下手。首先应从操作系统的角度看待整体问题,查看性能问题是否是由于操作系统级别对磁盘I/O参数、内存参数、网络参数或者对用户的一些限制所导致的。因此,在数据库中的响应时间又分为服务时间及等待时间:
响应时间=服务时间+等待时间
(1)服务时间
服务时间即数据库处理SQL语句的时间,包括语句的编译时间、语句的执行时间及数据在磁盘I/O上花费的时间等。
(2)等待时间
等待时间即数据库或者语句处理过程中遇到等待事件所耗费的时间,包括锁等待的时间、代理程序等待日志记录被清仓到磁盘所用的时间及Latch等待的时间。Latch是数据库内部的轻量级锁,主要是为了保证缓冲池中各种对象结构及配置文件的一致性。在后面的章节中会集中讲解Latch阻塞的一些问题及分析方法。
图1-3列举了一些服务时间及等待时间的例子,以及它们所占用的时间比例,我们可以看到,运行时间、编译时间、锁等待时间及磁盘I/O时间占用了绝大部分响应时间。
图1-3 DB2数据库时间耗费统计
1.1.2 吞吐量
吞吐量是对在单位时间内完成的工作量的度量值,包括:
● 每分钟完成的数据库事务;
● 每秒钟传送的文件千字节数;
● 每秒钟读或写的文件千字节数等。
并且响应时间与吞吐量有以下关系:
总交易数=响应时间×吞吐量
也就是说,在总交易数不变的前提下,响应时间与吞吐量成反比。在实际场景中,有时会发生响应时间不变但吞吐量增加的情况,对于这种情况我们也认为是发生了性能问题。
明确性能问题之后,就可以发掘影响性能问题的因素。应用的设计、程序的编写占据整体性能问题影响因素的很大比例,这些问题大多数都可以通过改动应用程序设计及改写程序来解决或改善。磁盘I/O问题又与系统硬件设计息息相关,就像一座立交桥,如果在设计上没有考虑到车流量问题(性能压力),在日后的运维工作中,也无法改变这个问题。由此可见,一个数据库系统如果在设计时没有充分考虑性能问题,则在整个系统的运维周期中都将有可能带来无法解决的性能问题。
在规划和调整任何系统中处理特定的工作负载时,一定要保证对响应时间和吞吐量都有明确的目标。否则,有可能在做一项费力而不讨好的事情。