目录sql
做者:庄廓然数据库
本次开发过程当中咱们用到了rails的orm框架,使用orm框架能够很方便地进行对象的关联和查询,例如查询一个用户的全部关注的社团能够用一下语句:ruby
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
可是若是你要返回一个社团列表,而且列表中包含关注该社团的人数,直接调用一下语句会致使查询效率下降app
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问题code
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_id
,value
对应的是关注者的个数
orm
{126833941=>1, 386008940=>2}
没有记录的社团对应的关注者就是0.对象
因此只用了一条查询记录便找到了全部社团的关注者的数量,提升了查询效率blog
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