数据库商业需求对性能的影响

  应用系统中的每一个功能在设计初衷肯定都是出于为用户提供某种服务,或者满足用户的某种需求,但是,并不是每一个功能在最后都能很成功,甚至有些功能的推出可能在整个系统中是画蛇添足。不仅没有为用户提高任何体验度,也没有为用户改进多少功能易用性,反而在整个系统中成为一个累赘,带来资源的浪费。不合理需求造成资源投入产出比过低需求是否合理很多时候可能并不是很容易界定,尤其是作为技术人员来说,可能更难以确定一个需求的合理性。即使指出,也不一定会被产品经历们认可。
  那作为技术人员的我们怎么来证明一个需求是否合理呢?
  第一、每次产品经理们提出新的项目(或者功能需求)的时候,应该要求他们同时给出该项目的预期收益的量化指标,以备项目上先后统计评估投入产出比率;
  第二、在每次项目进行过程中,应该详细记录所有的资源投入,包括人力投入,硬件设施的投入,以及其他任何项目相关的资源投入;
  第三、项目(或者功能需求)上线之后应该及时通过手机相关数据统计出项目的实际收益值,以便计算投入产出比率的时候使用;
  第四、技术部门应该尽可能推动设计出一个项目(或者功能需求)的投入产出比率的计算规则。在项目上线一段时间之后,通过项目实际收益的统计数据和项目的投入资源量,计算出整个项目的实际投入产出值,并公布给所有参与项目的部门知晓,同时存放以备后查。有了实际的投入产出比率,我们就可以和项目立项之初产品经理们的预期投入产出比率做出比较,判定出这个项目做的是否值得。而且当积累了较多的项目投入产出比率之后,我们可以根据历史数据分析出一个项目合理的投入产出比率应该是多少。这样,在项目立项之初,我们就可以判定出产品经理们的预期投入产出比率是否合理,项目是否真的有进行的必要。有了实际的投入产出比率之后,我们还可以拿出数据给老板们看,让他知道功能并不是越多越好,让他知道有些功能是应该撤下来的,即使撤下该功能可能需要投入不少资源。实际上,一般来说,在产品开发及运营部门内部都会做上面所说的这些事情的。但很多时候可能更多只是一种形式化的过程。在有些比较规范的公司可能也完成了上面的大部分流程,但是要么数据不公开,要么公开给其他部门的数据存在一定的偏差,不具备真实性。为什么会这样?其实就一个原因,就是部门之间的利益冲突及业绩冲突问题。产品经理们总是希望尽可能的让用户觉得自己设计的产品功能齐全,让老板觉得自己做了很多事情。但是从来都不会去关心因为做一个功能所带来的成本投入,或者说是不会特别的关心这一点。而且很多时候他们也并不能太理解技术方面带来的复杂度给产品本身带来的负面影响。
  这里我们就拿一个看上去很简单的功能来分析一下。
  需求:一个论坛帖子总量的统计
  附加要求:实时更新
  在很多人看来,这个功能非常容易实现,不就是执行一条SELECTCOUNT(*)的Query就可以得到结果了么?是的,确实只需要如此简单的一个Query就可以得到结果。但是,如果我们采用不是MyISAM存储引擎,而是使用的Innodb的存储引擎,那么大家可以试想一下,如果存放帖子的表中已经有上千万的帖子的时候,执行这条Query语句需要多少成本?恐怕再好的硬件设备,恐怕都不可能在10秒之内完成一次查询吧。如果我们的访问量再大一点,还有人觉得这是一件简单的事情么?既然这样查询不行,那我们是不是该专门为这个功能建一个表,就只有一个字段,一条记录,就存放这个统计量,每次有新的帖子产生的时候,都将这个值增加1,这样我们每次都只需要查询这个表就可以得到结果了,这个效率肯定能够满足要求了。确实,查询效率肯定能够满足要求,可是如果我们的系统帖子产生很快,在高峰时期可能每秒就有几十甚至上百个帖子新增操作的时候,恐怕这个统计表又要成为大家的噩梦了。要么因为并发的问题造成统计结果的不准确,要么因为锁资源争用严重造成整体性
  能的大幅度下降。其实这里问题的焦点不应该是实现这个功能的技术细节,而是在于这个功能的附加要求“实时更新”上面。当一个论坛的帖子数量很大了之后,到底有多少人会关注这个统计数据是否是实时变化的?
  有多少人在乎这个数据在短时间内的不精确性?我想恐怕不会有人会傻傻的盯着这个统计数字并追究当自己发了一个帖子然后回头刷新页面发现这个统计数字没有加1吧?即使明明白白的告诉用户这个统计数据是每过多长时间段更新一次,那有怎样?难道会有很多用户就此很不爽么?
  只要去掉了这个“实时更新”的附加条件,我们就可以非常容易的实现这个功能了。就像之前所提到的那样,通过创建一个统计表,然后通过一个定时任务每隔一定时间段去更新一次里面的统计值,这样既可以解决统计值查询的效率问题,又可以保证不影响新发贴的效率,一举两得。
  实际上,在我们应用的系统中还有很多很多类似的功能点可以优化。如某些场合的列表页面参与列表的数据量达到一个数量级之后,完全可以不用准确的显示这个列表总共有多少条信息,总共分了多少页,而只需要一个大概的估计值或者一个时间段之前的统计值。这样就省略了我们的分页程序需要在分以前实时COUNT出满足条件的记录数。
  其实,在很多应用系统中,实时和准实时,精确与基本准确,在很多地方所带来的性能消耗可能是几个性能的差别。在系统性能优化中,应该尽量分析出那些可以不实时和不完全精确的地方,作出一些相应的调整,可能会给大家带来意想不到的巨大性能提升。无用功能堆积使系统过度复杂影响整体性能很多时候,为系统增加某个功能可能并不需要花费太多的成本,而要想将一个已经运行了一段时间的功能从原有系统中撤下来却是非常困难的。
  首先,对于开发部门,可能要重新整理很多的代码,找出可能存在与增加该功能所编写的代码有交集的其他功能点,删除没有关联的代码,修改有关联的代码;
  其次,对于测试部门,由于功能的变动,必须要回归测试所有相关的功能点是否正常。可能由于界定困难,不得不将回归范围扩展到很大,测试工作量也很大。
  最后,所有与撤除下线某个功能相关的工作参与者来说,又无法带来任何实质性的收益,而恰恰相反是,带来的只可能是风险。
  由于上面的这几个因素,可能很少有公司能够有很完善的项目(或者功能)下线机制,也很少有公司能做到及时将系统中某些不合适的功能下线。所以,我们所面对的应用系统可能总是越来越复杂,越来越庞大,短期内的复杂可能并无太大问题,但是随着时间的积累,我们所面对的系统就会变得极其臃肿。不仅维护困难,性能也会越来越差。尤其是有些并不合理的功能,在设计之初或者是刚上线的时候由于数据量较小,带来不了多少性能损耗。可随着时间的推移,数据库中的数据量越来越大,数据检索越来越困难,对真个系统带来的资源消耗也就越来越大。
  而且,由于系统复杂度的不断增加,给后续其他功能的开发带来实现的复杂度,可能很多本来很简单的功能,因为系统的复杂而不得不增加很多的逻辑判断,造成系统应用程序的计算量不断增加,本身性能就会受到影响。而如果这些逻辑判断还需要与数据库交互通过持久化的数据来完成的话,所带来的性能损失就更大,对整个系统的性能影响也就更大了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注