作者:庄廓然

问题简述

本次开发过程中我们用到了rails的orm框架,使用orm框架可以很方便地进行对象的关联和查询,例如查询一个用户的所有关注的社团可以用一下语句:

list = @user.followed_clubs

#user.rb模型中添加
#user和club是多对多的关系,一个user可以关注多个club,一个club也可以有多个关注者
has_many :user_follow_clubs, dependent: :destroy
has_many :followed_clubs, through: :user_follow_clubs, source: :club #club.rb模型中添加
has_many :user_follow_clubs, dependent: :destroy
has_many :follow_users, through: :user_follow_clubs, source: :user

但是如果你要返回一个社团列表,并且列表中包含关注该社团的人数,直接调用一下语句会导致查询效率降低

list = @user.followed_clubs
result = []
list.each do |club|
result.append(
{
club_id: club.id,
followers: club.follow_users.count
#该语句会导致在每个club中调用如下sql语句
}
)
end
SELECT COUNT(*) FROM `users` INNER JOIN `user_follow_clubs`
ON `users`.`id` = `user_follow_clubs`.`user_id` WHERE `user_follow_clubs`.`club_id` = xxxx

也就是查询一个社团列表调用了N次额外的查询。

查询主数据,是1次查询,查询出n条记录;根据这n条主记录,查询从记录,共需要n次,所以叫数据库1+n问题

问题解决

group的方法简化查询

list = @user.followed_clubs.ids
count_hash = UserFollowClub.where(club_id: list).group(:club_id).count
SELECT COUNT(*) AS count_all, `user_follow_clubs`.`club_id` AS user_follow_clubs_club_id FROM `user_follow_clubs` WHERE `user_follow_clubs`.`club_id` IN (1033447816, 126833941, 386008940) GROUP BY `user_follow_clubs`.`club_id`

最终得到一个hash,key对应的是club_idvalue对应的是关注者的个数

{126833941=>1, 386008940=>2}

没有记录的社团对应的关注者就是0.

所以只用了一条查询记录便找到了所有社团的关注者的数量,提高了查询效率

改正后的代码

list = @user.followed_clubs
id_list = list.ids
count_hash = UserFollowClub.where(club_id: id_list).group(:club_id).count
list.each do |club|
result.append(
{
club_id: club.id,
followers: count_hash[club.id]
}
)
end

[技术博客] 数据库1+N查询问题的更多相关文章

  1. 一文搞定scrapy爬取众多知名技术博客文章保存到本地数据库,包含:cnblog、csdn、51cto、itpub、jobbole、oschina等

    本文旨在通过爬取一系列博客网站技术文章的实践,介绍一下scrapy这个python语言中强大的整站爬虫框架的使用.各位童鞋可不要用来干坏事哦,这些技术博客平台也是为了让我们大家更方便的交流.学习.提高 ...

  2. ******IT公司面试题汇总+优秀技术博客汇总

    滴滴面试题:滴滴打车数据库如何拆分 前端时间去滴滴面试,有一道题目是这样的,滴滴每天有100万的订单,如果让你去设计数据库,你会怎么去设计? 当时我的想法是根据用户id的最后一位对某个特殊的值取%操作 ...

  3. 50家硅谷IT公司技术博客

    分享一下 50 家硅谷优秀 IT 公司技术博客,从中可以了解企业文化,技术特色和设计语言,如果直接列出来很单调,加上点评,算吐槽版吧. 知名大厂   1. Facebook https://www.f ...

  4. [技术博客]使用CDN加快网站访问速度

    [技术博客]使用CDN加快网站访问速度 2s : most users are willing to wait 10s : the limit for keeping the user's atten ...

  5. 技术博客——微信小程序的架构与原理

    技术博客--微信小程序的架构与原理 在两个月的微信小程序开发过程中,我曾走了不少弯路,也曾被很多现在看来十分可笑的问题所困扰.这些弯路与困扰,基本上都是由于当时对小程序的架构理解不够充分,对小程序的原 ...

  6. [技术博客] 软工-Ruby on Rails 后端开发总结分享

    [技术博客] 软工-Ruby on Rails 后端开发总结分享 在这次软件编写中,我们的后端使用了Ruby on Rails (RoR)框架. Rails框架是用Ruby编写的.这意味着当我们为Ru ...

  7. [技术博客] Django中文件的保存与访问

    [技术博客] Django中文件的保存与访问 在TextMarking项目开发中,数据库需要保存用户上传的文本文档. 原型设计:用户点击上传文本->保存文本->文本发送到后端保存为文件. ...

  8. 【转】【技术博客】Spark性能优化指南——高级篇

    http://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651745207&idx=1&sn=3d70d59cede236e ...

  9. [转]有哪些值得关注的技术博客(Java篇)

    有哪些值得关注的技术博客(Java篇)   大部分程序员在自学的道路上不知道走了多少坑,这个视频那个网站搞得自己晕头转向.对我个人来说我平常在学习的过程中喜欢看一些教程式的博客.这些博客的特点: 1. ...

随机推荐

  1. 2019-08-01 Ajax实现从数据库读取表

    php代码 <?php //用pdo连接数据库 $dsn = 'mysql:host=127.0.0.1;port=3306;charset=utf8;dbname=news'; //实例化PD ...

  2. Java 之 Arrays 类

    一.概述 java.util.Arrays 此类包含用来操作数组的各种方法.比如排序和搜索等,其所有方法均为静态方法,调用非常方便. 二.操作数组的方法 (1)使用二分搜索法来搜索指定的 int 型数 ...

  3. JavaScript 简单类型和复杂类型区别

    一.基本类型 1.概述 值类型又叫做基本数据类型,简单数据类型.在存储时,变量中存储的是值本身,因此叫做值类型 2.基本类型在内存中的存储 基本数据类型存储在栈区中. 3.基本类型作为函数的参数 基本 ...

  4. UIDatePicker基本使用

    UIDatePicker提供了一个快速选择日期和时间的控件,他是UIControl的子类,专门用于日期时间的选择.其样式可以通过UIDatePicker的属性进行灵活设置,同时也可以获取到当前UIDa ...

  5. Django下JWT的使用

    前言 JWT 是 json web token 的缩写, token的作用你应该已经了解,用于识别用户身份避免每次请求都需要验证 用来解决前后端分离时的用户身份验证 在传统的web项目中 我们会在fo ...

  6. k8s 初识pod (二)

    kubernetes中调用pod到哪个节点上是无关紧要的,但由于实际情况,每台node的硬件环境不一致,所以某些情况要求将不同pod调到指定节点上运行.也可以通过label实现. kubectl la ...

  7. SaltStack--接口salt-api

    SaltStack接口salt-api 介绍 参考官档参考官档 SaltStack官方提供有REST API格式的salt-api项目,将使salt与第三方系统集成变得更加简单. salt-api安装 ...

  8. 论文笔记系列-Auto-DeepLab:Hierarchical Neural Architecture Search for Semantic Image Segmentation

    Pytorch实现代码:https://github.com/MenghaoGuo/AutoDeeplab 创新点 cell-level and network-level search 以往的NAS ...

  9. httprunner学习17-linux上安装httprunner环境

    前言 如果你是在linux上安装httprunner环境,用的是python3的环境,安装成功后会发现hrun命令找不到,需添加软链接. 环境准备: centos 7.6 python 3.6 htt ...

  10. centos设置开机自启动脚本

    1.新建脚本文件 我这里是为了设置开机自动设置ipv6隧道,所以命名为ipv6tunnel.sh ifconfig sit0 up ifconfig sit0 inet6 tunnel ::66.22 ...