但是在笔者工作经验中,常常看见一些企业没有弄清楚自己的业务类型到底是什么,搞不清楚自身系统的瓶颈究竟在哪里,就开始盲目的寻求系统优化的方法,结果不但对系统性能没有任何的提高,甚至可能带来适得其反的效果。
因此,在进行系统优化之前,搞清楚自己的业务类型是非常重要的,只有确定清除自身的业务类型后,才有可能对症下药对系统进行优化。一般而言,数据库系统的类型通常包括两种类型:OLTP和OLAP。
OLTP对服务器CPU的影响
OLTP,也叫联机事务处理(Online Transaction Processing),表示事务性非常高的系统,一般都是高可用的在线系统,以小的事务以及小的查询为主。在评估其系统的时候,一般看其每秒执行的transaction以及execute sql的数量。
在这样的系统中,每秒处理的transaction往往超过几百个,或者是几千个,select 语句的执行量每秒几千甚至几万个。典型的OLTP系统如电子商务系统,银行,证卷等等,如美国ebay的业务数据库,就是很典型的OLTP数据库。
OLTP系统最容易出现的瓶颈就是服务器系统的CPU与磁盘子系统。
CPU的损耗取决于逻辑读以及内部调用的执行频度,如函数等等。对于这种类型的损耗,最有效的优化措施是对数据库语句做一定的优化。
例如,一个执行频繁的SQL语句,即使每个语句只减少了很少的逻辑读,也相当于优化了逻辑读很差的大型语句,对整体系统性能能有较大的提高。很多人似乎感觉不到这里的作用,觉得一个语句几十个逻辑读,执行时间基本为0,就不需要优化了。其实,只要他的执行的频次非常频繁,而且有优化的余地,就一定要优化。减少一定的逻辑读或者降低执行次数,都是有效的优化方法。
此外,数据库系统中一些计算性的函数,如sum,count,decode被非常频繁的使用,也会产生相当大的CPU损耗,笔者就曾经遇到一个系统,因为一个sql语句,大量的使用了sum与decode进行行列转换,结果这一个语句就耗费了整个机器一半以上的CPU。
在一般的OLTP系统中,如果不考虑笔者上面所说的函数问题,那么,逻辑读乘以执行次数,就决定了cpu的消耗程度。
比如一个语句,每秒执行次数为500次,每个逻辑读为15,但是,通过优化,能让每个语句的逻辑读从15降到10,那么,每秒的逻辑读就可以减少500*5=2500个,其实就是相当于优化了一个执行频率为每秒1次,每次逻辑读为2500个的语句(注意,2500个逻辑读,在OLTP系统中是非常差的语句)。
再比如,我们假定一个1GHZ的cpu每秒能正常处理的逻辑读是100,000个,假定每个语句都包括10个逻辑读,那么这样的语句CPU每秒可以处理10,000个,而1000个逻辑读一个的语句,每秒则只能处理100个。很显然前一种情况相比后一种情况速度提升很多,因此整体系统的运行效率能够大幅度的提高。而当我们确定数据库的逻辑读速度后,我们也可以根据数据库的运行负荷来选择或者扩充服务器CPU。
OLTP对存储系统的影响
我们在上面分析了OLTP的语句形式不同,对CPU不同的运行压力。同样的道理,物理读乘以执行次数,就决定了存储子系统的处理能力。
在一个OLTP环境中,物理读一般都是db file sequential read决定的,也就是单块读,一个典型的OLTP系统,db file sequential read应当基本等于磁盘子系统的读IOPS。而磁盘子系统的IOPS处理能力,则是与cache命中率以及磁盘个数有很大的关系。
在我此前的一些文章中,曾经详细分析过磁盘系统IOPS能力与缓存、cache命中率的关系。请参考RAID5和RAID10,哪种RAID适合你(下),在我的这篇文章中,我们发现一个15K转速的磁盘,每秒最多能处理的iops达到150个,基本就达到该磁盘的性能极限。在cache完全不命中的情况下, 100个磁盘最多能处理的IOPS也仅仅是15000个,而实际上,考虑到一些其他不可见的损耗,大多数都达不到这个值。因此提高cache命中率对于提高存储子系统的运行效率至关重要。
OLTP数据库系统中最常用的技术就是cache技术与btree索引,通过各种有效的方式提高cache命中率,从而决定了很多语句不需要从磁盘子系统获得数据,因此能够大大的提高磁盘读取的速度。也因此,web cache与oracle data buffer对OLTP系统是很重要的。
另外,在索引使用方面,语句是越简单越好,而且一定要使用绑定变量,减少语句解析,尽量减少关联,这样的好处是执行计划较为简单稳定。
其它方面,基本不使用分区技术,MV技术,并行技术以及位图索引,因为并发量很高,批量更新可能要尽量快速提交避免阻塞的发生。
根据笔者的经验,在美国ebay电子交易网站的数据库设计中,有一个很重要的点就是,数据库只负责存放数据,业务逻辑尽量在业务层实现,因为数据库扩展是困难的,而应用服务器扩展是简单的。这种规划是非常合理的,也就是说,在高可用的OLTP环境中,数据库使用越简单的功能越好。
寻找OLAP的瓶颈
OLAP,也叫联机分析(Online Analytical Processing),有的时候也叫DSS决策支持系统,就是我们说的数据仓库。比较典型的系统包括一些高校的图书馆系统、医院的PACS系统等等。
在这样的系统中,语句的执行量不是考核标准,因为一个语句的执行时间可能会非常长,读取的数据也非常多。所以,这样的系统中,考核的标准往往决定于磁盘子系统的吞吐量。
磁盘子系统的吞吐量直接取决于磁盘的个数,这个时候cache基本对整体系统没有太多的影响,这个时候数据库的读写基本上是db file scattered read与direct path read/write。
在我前面的文章RAID5和RAID10,哪种RAID适合你(下)中就描述过,如果一个15K的磁盘的IO量每秒13M,那么,100个磁盘,最多能提供的吞吐量则是1300M/s(实际上,也基本达不到这个值)。在磁盘个数足够的情况下,还需要考虑采用比较大的带宽,如4GB的光纤接口。
在OLAP系统中,常使用的技术有分区技术,并行技术。如分区技术可以使得一些大表的扫描变得很快(只扫描单个分区),而且方便管理。另外,如果分区结合并行的话,也可以使得整个表的扫描也会变得很快。
并行技术除了与分区技术结合外,在oracle 10g中,与rac结合实现多节点的同时扫描,效果也非常不错,把一个任务,如select的全表扫描,平均的分派到多个rac的节点上去。
在OLAP系统中,不需要使用绑定变量,因为整个系统的执行量很少,分析时间对于执行时间来说,可以忽略,而且避免出现错误的执行计划。但是OLAP中可以大量使用位图索引,物化视图,对于大的事务,尽量的寻求速度上的优化,没有必要象OLTP需要快速提交,甚至要刻意减慢执行的速度。
总结:选择合适的优化方法
这两种不同的业务类型需要不同的优化方式,特别是在高可用的OLTP环境中,不要盲目的把OLAP的技术拿过来用,如分区技术,如果不是大范围的使用了分区关键字作为where条件,而采用其它的字段作为where条件,那么,如果是本地索引,你将不得不扫描多个索引,而使得性能变的更为低下。如果是全局索引,那分区的意义又何在,只是多出一份分区技术的license而已。
并行技术也是如此,一般是在大型任务的时候才使用,好比说,实际生活中,一个比较大型的工作,如翻译一本书,你可以先安排多个人,每个人翻译不同的章节,这样是可以提高翻译速度,但是,你现在只是翻译一页,你也去分配不同的人翻译不同的行,再组合起来,这个时间,你一个人或者早就翻译完了。
位图索引如果用在oltp环境中,可能因为阻塞范围太大,很容易阻塞与死锁,但是,在olap环境中,可能会因为其特有的特性,提高olap的查询速度。mv也是基本一样,包括触发器等等,在dml频繁的oltp系统上,很容易成为瓶颈,而在olap环境上,则可能会因为使用恰当而提高查询速度。
因此,在实际的系统维护过程中,大家需要慢慢的体会,分清楚业务类型,再判断合适的系统优化方法,不能盲目拿来使用。