mysql - 使用事件记录轨优化查询

标签 mysql sql ruby-on-rails postgresql

rails模型中的DB关系:

Class User < ActiveRecord::Base
  has_many :user_messages
  has_many :messages
end

Class UserMessage < ActiveRecord::Base
  belongs_to :user
  belongs_to :message
end

Class Message < ActiveRecord::Base
  belongs_to :user
  has_many :user_messages
end

我想优化以下代码:

ids.each do |id|
  user = User.find_by_id(id)
  unread_count = user.user_messages.where(:folder => user.inbox_id, :read => false).count
  puts "UserID #{id} ---- Unread Message count #{unread_count}"
end

有人可以告诉我如何使用 Active record 或 SQL 查询来优化上述代码吗?我基本上想减少数据库查询和上述代码完成循环所需的时间。

提前致谢。

最佳答案

你可以这样做:

users = User.where(id: ids).includes(:user_messages)
users.each do |user|
  unread_count = user.user_messages.where(:folder => user.inbox_id, :read => false).count
  puts "UserID #{user.id} ---- Unread Message count #{unread_count}"
end

既然你急于加载user_messages ,它不会在循环内触发任何其他数据库查询。只需 1 个查询即可获取用户,即 user_messages。

或者你可以这样做:

user_messages = UserMessage.joins(:user).where('folder = users.inbox_id AND read = false').group(:user_id).count
# user_messages = {1=>10, 2=>19}
# Here keys are user ids and values are no of user_messages for that user

user_messages.each do |user_id,unread_msg_count|
  puts "UserID #{user_id} ---- Unread Message count #{unread_msg_count}"
end

PS:我没有测试任何代码,如果有错误请评论。我假设这里 puts "UserID #{ids}您想放置一个用户ID并根据它修改我的代码,因为在您的代码中它将打印所有ID ids .

关于mysql - 使用事件记录轨优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41324507/

相关文章:

MySQL:从日期/时间戳列返回日期的 SQL 查询

SQL Server 日期范围

ruby-on-rails - Rails 3 用户时区

php - 是否可以在单个查询中将多对多关系与一对多关系组合起来?

mysql - phpMyAdmin - 错误您应该升级到 MySQL 5.5.0 或更高版本

Mysql LIMIT 使用 MATCH AGAINST

ruby-on-rails - 在 Rails 中调用一个 Action 时调用不同的 Action

ruby-on-rails - Rails 中的推荐引擎

mysql - 如何在交叉表查询中聚合不重复的数据

mysql - SQL 标准 UPSERT 调用