SQL请求优化——请求次数统计,SQL写操作稀释

引言

  前几天做了这么一个东西:一个游戏中有个活动页面,活动页面有个商品,商品下面要显示该商品实浏览次数,就相当于是用户每出发一次请求这个浏览总次数都会添加一次,这个问题很简单,每次浏览的时候去数据库中进行“+1”操作即可。但是做完之后想想,由于这个浏览总次数实时性要求不是那么高,我就可以对sql请求进行稀释、减少“+1”的请求次数,这样可以减少与数据库交互时“写操作”所浪费的资源。

 

实现

  这种特殊环境下的sql请求是这样的,每次要执行浏览次数“+1”操作时,我们产生一个1~N的随机数R,如果R%N == 0则进行“+N”操作,N可以根据浏览总次数的实时性等级进行适当的调整,实时性越高,N越小,写操作命中的几率越大,否则反之,看看下面的示意图:

  下面是部分代码(只是测试模拟的,重在说明意思):

 1 class Addtimes{
 2     /**
 3      * 假设这个是db对象
 4      */
 5     private static $db;
 6 
 7     /**
 8      * 测试“浏览次数”稀释
 9      * int $hit 稀释的倍率,平均$hit进行一次记录
10      */
11     public static function doadd($hit){
12         $hit     = intval($hit);
13         $r         = rand(1,$hit);
14         $r % $hit == 0 && self::$db->query("update testtimes set times=times+{$hit}");
15     }
16 }

  这样就从一定程度上面减少了每次进行写操作,把N次写操作合并为一次。

 

总结

  这个是一个小小的优化,但他的局限性很大,使用的时候要注意下面几点:

  1. 使用之前要考虑数据实时性的要求,实时性要求高的还是别用了。
  2. 这个预期总次数一定要大于N,最好是好多倍,由于是随机数进行的,如果总次数太少会出现很大的误差。
  3. 如果可以使用缓存的话,会更好,比如将次数存储在memchached、redis、apc等缓存中,每次都进行“+1”操作,这样就可以实现高实时性;命中次数逻辑依然存在,当命中时进行数据持久化(回写db),这时候这个回写次数N就可以适当的调大。

  本文版权归作者(luluyrt@163.com)和博客园共有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

posted @ 2014-12-21 19:41  奔跑的Man  阅读(2189)  评论(4编辑  收藏  举报