前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >以关联表中的count计数作为主表的排序依据(进阶版)

以关联表中的count计数作为主表的排序依据(进阶版)

作者头像
世纪访客
发布2018-08-02 15:37:18
9720
发布2018-08-02 15:37:18
举报
文章被收录于专栏:西枫里博客西枫里博客
...
...

上一篇文章在最后提到“在foreach循环中嵌套查询,这是非常耗费资源的”。当时考虑到本站应用场景简单,查询仅为百位数量级,性能损失忽略不计,就图简单没有深入去重写程序。今天得空,改造了下程序,通过操作数组来达到避开在遍历中使用count查询的目的。

先来通过thinkPHP的debug函数来测试下昨天的程序性能。
代码语言:javascript
复制
public function tagslst($num)
    {
        debug('begin');
        $tagRes=Db::name('tags')->select();
        foreach ($tagRes as $key => $value) {
            $tagsnum=Db::name('art_tag')->where('tags_id',$value['id'])->count();
            $tagsRes[$key]=array('sort'=>$tagsnum,'id'=>$value['id'],'tag_name'=>$value['tag_name']);//构造键名为sort,键值为count计数的新数组
        }
        foreach ($tagsRes as $k => $v) {
            $sort[]=$v['sort'];
        }
        array_multisort($sort, SORT_DESC, $tagsRes);//按tags数多少重新排序数组
        $tagsRes=array_slice($tagsRes,0,$num);//返回指定部分数据
        debug('end');
        dump(debug('begin','end').'s');
        dump(debug('begin','end','m').'kb');die;
        return $tagsRes;
    }

测试结果:运行耗时0.05s,内存占用112k。如图:

未标题-1.jpg
未标题-1.jpg
尝试颠倒查询顺序,通过内置数组函数进行计数。

上一篇是正常思维,通过查询tag表中的id在关联表中做count查询查询,最后以count依据截取需要的部分内容返回给控制器。缺陷在上一篇中提到,将第一步结果遍历后,代入count计数,有多少条数据就要查询多少次数据库,这个性能损失非常大。

今天换个思路来实现相同的目的。首先通过查询中间表中的tags_id列,将查询结果通过array_count_values函数做一个计数操作(关键就在这里,通过使用数组来计数达到避开循环中使用count查询)。后续对这个数组截取需要的部分在tag表中使用in查询,返回最终查询结果即可。代码如下:

代码语言:javascript
复制
public function tagslst($num)
    {
        debug('begin');
        $tagidRes=Db::name('art_tag')->field('tags_id')->select();
        foreach ($tagidRes as $key => $value) {
            $tagids[]=$value['tags_id'];
        }
        $tagids=array_count_values($tagids);
        arsort($tagids);

        $tagids=array_slice($tagids,0,$num,true);
        
        foreach ($tagids as $k => $v) {
            $tag_idRes[]=$k;
        }

        $map['id']=['in',$tag_idRes];
        $tagRes=Db::name('tags')->where($map)->select();
        foreach ($tagRes as $key => $value) {
            foreach ($tag_idRes as $k => $v) {
                if($value['id']==$v){
                   $tagsRes[$k]=$value; 
                }
            }
        }
        ksort($tagsRes);
        debug('end');
        dump(debug('begin','end').'s');
        dump(debug('begin','end','m').'kb');die;
        return $tagsRes;
    }

同样,也使用debug函数测试下相应的性能数据。得到结果如下:

未标题-2.jpg
未标题-2.jpg

和前面的数据进行对比可见,耗时节约70%,内存消耗减少50%以上。性能提升还是非常明显的。性能提升的关键在用PHP数组内置函数去代替了count计数查询,第二是截取需要的部分进行最后的数据查询。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先来通过thinkPHP的debug函数来测试下昨天的程序性能。
  • 尝试颠倒查询顺序,通过内置数组函数进行计数。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档