ruby-on-rails - 使用 2 列之间的差异加速数据库查询:created_at 和 updated_at
问题描述
在我的 Rails 项目中,我有一个Message
模型,我的数据库中有数十万条消息。它还有一个“状态”列,可以“排队”或“已交付”。
创建消息后,其状态变为“已排队”,显然该created_at
字段已填充。一段时间后(我不会详细说明如何),该消息的状态将变为“已发送”。
现在,对于数十万条消息,我想按它们的传递时间对它们进行分组。换句话说,计算和之间的差异,updated_at
并将created_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
?
谢谢。
解决方案
可能是您需要正确的索引。
您需要索引的字段是:
- 方向
- 地位
- 帐户ID
- created_at
因此,在迁移中添加以下索引:
add_index :messages, [:direction, :status, :account_id, :created_at]
一些数据库,包括 postgresql,可以索引表达式。为了获得最佳结果,请将 ( updated_at - created_at
) 作为您的第五个值添加到索引中。您必须使用 SQL 而不是 rails 迁移来创建它。
我不会担心在索引表上创建记录所增加的时间。我只是不会担心它。
推荐阅读
- r - 如何在R中迭代地填充向量的向量
- c - 如何通过 shell 脚本将整数值传递给 C 程序可执行文件?
- java - 我应该在春天创建一个单独的配置类吗?如果是这样,我该怎么做?
- python - 将多个python文件转换为exe的替代方法
- django - 给出正确密码时,postgres 显示身份验证失败
- python - 这些 if 语句背后的逻辑是什么?
- sql - 减少像 DISTINCT 这样的重复记录,结果集必须是正确的顺序
- javascript - 如何使用按钮将一行向上移动一排
- javascript - 如何将内联样式添加到 React 组件作为道具?
- c++ - 为什么这些字符串不相等