ruby-on-rails - 使用 2 列之间的差异加速数据库查询 : created_at and updated_at

标签 ruby-on-rails postgresql activerecord indexing

在我的 Rails 项目中,我有一个 Message 模型,我的数据库中有数十万条消息。它还有一列“状态”,可以是“排队”或“已送达”。

创建消息时,其状态变为“已排队”,显然 created_at 字段已填充。一段时间后(我不会详细说明如何),该消息的状态将变为“已发送”。

现在,对于数十万条消息,我想按发送时间对它们进行分组。换句话说,计算updated_atcreated_at之间的差异,并将它们分为0-3分钟、3-5分钟、5-10分钟和10分钟以上。

我目前的做法是

delivery_time_data = []
    time_intervals = [{lb: 0.0, ub: 180.0}, {lb: 180.0, ub: 300.0}, {lb: 300.0, ub: 600.0},{lb: 600.0, ub: 31*3600*24}]
    time_intervals.each_with_index do |ti, i|
      @messages = Message.where(account_id: @account.id)
                      .where(created_at: @start_date..@end_date)
                      .where(direction: 'outgoing')
                      .where(status: Message::STATUS_DELIVERED)
                      .where('status_updated_at - created_at >= ?', "#{ti[:lb]} seconds")
                      .where('status_updated_at - created_at < ?', "#{ti[:ub]} seconds")
      if i == time_intervals.count - 1
        delivery_time_data.push([i+1, "Greater than #{ti[:lb]/60.to_i} minutes", @messages.count])
      else
        delivery_time_data.push([i+1, "#{ti[:lb]/60.to_i} minutes to #{ti[:ub]/60.to_i} minutes", @messages.count])
      end

它有效。但它非常慢,当我有大约 200000 条消息时,服务器可能会崩溃。

如果我希望创建消息的频率相当高,那么在 created_at 上添加索引是否是个好主意?

谢谢。

最佳答案

可能是您需要正确的索引。

需要索引的字段是:

  • 方向
  • 状态
  • 帐号编号
  • 创建于

因此在迁移中添加以下索引:

add_index :messages, [:direction, :status, :account_id, :created_at]

一些数据库,包括 postgresql,可以在表达式上建立索引。为获得最佳结果,添加 (updated_at - created_at) 作为要索引的第五个值。您必须使用 SQL 而不是 Rails 迁移来创建它。

我不会担心在索引表上创建记录会增加时间。 我只是不担心。

关于ruby-on-rails - 使用 2 列之间的差异加速数据库查询 : created_at and updated_at,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56065674/

相关文章:

ruby-on-rails - Rails回溯消音器不起作用,而过滤器起作用

ruby-on-rails - 带有 VI 命令的 Windows 最佳 Ruby 编辑器

mysql - YII 库存控制系统问题

mysql - 与 ActiveRecord 和 Sinatra 的多维 JOIN

postgresql - 如何解释以下 PostgreSQL 查询计划

php - Codeigniter 使用事件记录选择自定义

html - 如何提高渲染 html 速度

ruby-on-rails - 即使我的应用程序使用 bundler ,我是否需要将 passenger 作为常规 gem 安装?

sql - PostgreSQL 中大写名称的正则表达式检查

sql - postgresql 连接查询