冗余之美

来源:互联网 发布:html 加载js顺序 编辑:程序博客网 时间:2024/04/27 16:59


        最近接到一个项目设计工作,这个项目曾经做过一期,但只上线了十几个客户端就出了很多难以克服的问题:数据同步问题(项目有客户端数据库以支持离线操作),查询效率问题,占用网络带宽太大的问题等等,不得已只好重做了,今天说冗余之美,也根这个项目有一点的关系。


      在分析查询效率时,发现该查询的确复杂,连接了好向张表,而且在SELECT里还涉及大量计算,一个SQL语句长达数KB,忽略网络因素,该语句在数据库中单次查询的时间就高达近2秒(ORACLE),后对其索引进行了近一步优化,但查询时间还是超过了一秒,仔细分析,发现连接的好几张表中有一些是VIEW,而且发现期中一个VIEW单查数据就得近一秒,初步锁定的最大的问题,后发现其实该VIEW无非也是连接了一些表并进行了计算拼出了一些字段值,拼了不到十个字段,代价却是如此之大,后续的优化方法就较简单了,去掉没必要的VIEW,而改用冗余字段的形式,这些冗余的插入和更新代价并不大,但却大大提高了查询的效率,最终的结果的单次查询为200ms同内,达到了预期的效果。


        类似的例子其时也时常遇到。比如最常见的用户管理中,用户与角色是多对多关系,角色与功能也是多对多,如果我们经常要用到用户与功能的的对应关系,一般情况下就是连合查询建了索引且数据量不大,并发数据不多的情况下不会有问题。但如果现有性能无法满足了该怎么办呢?建一张冗余表也许是一个好的选择,因为这类数据变化并不大也不频繁,因此维护冗余表的代价也不太大,但却大大提高了查询效率(至少一半以上)


        抛开这些不说,在实际的代码编写中也会有一些例子,记得在高效C++书中也提到过over-eager evaluation概念,当然如果称之为冗余计算也许并不合适,但实际上该思想就是利用可能冗余的计算来达到提高代码效率的目的,一个应用是磁盘读取时,如果用户只要读几个字节,我们可能会将该字节前后的数据也一起读进来,当然这也有一些权衡,比如说,某类业务明摆着用户只关心那么一点点,你还去做更多的工作,那是白干,但在上面的例子中,根据经验,当一个用户需要数据的时候,往往也需要这些数据附近的数据,这样,这种冗余读取就带来了很高的性能提升。

原创粉丝点击