在我的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
上添加索引甚至是个好主意吗?
谢谢。
答案 0 :(得分:2)
可能您需要正确的索引。
您需要索引的字段是:
因此,在迁移中添加以下索引:
add_index :messages, [:direction, :status, :account_id, :created_at]
某些数据库,包括postgresql,可以在表达式上建立索引。为了获得最佳结果,请添加(updated_at - created_at
作为第五个索引值。您将必须使用SQL而不是rails迁移来创建它。
我不用担心在索引表上创建记录所花费的时间。 我只是不用担心。