【发布时间】:2018-07-11 02:24:27
【问题描述】:
我正在尝试显示一个表格,该表格对 webhook 进行计数,并将各种计数按 date_sent、sending_ip 和 esp(电子邮件服务提供商)排列到单元格中。在每个单元格中,控制器需要计算标记为“打开”事件和“发送”事件的 webhook。我们的数据库目前包含数百万个 webhook,并且每天至少增加 100k。这个过程已经花费了很长时间,以至于运行这个索引方法实际上是没有用的。
我希望 Rails 可以使用这样的一行将庞大的模型分解为更小的列表:
@today_hooks = @m_webhooks.where(:date_sent => this_date)
我认为这行之后的查询只会查看部分列表,而不是完整模型。不幸的是,运行这个索引方法会生成数百条 SQL 语句,它们都看起来像这样:
SELECT COUNT(*) FROM "m_webhooks" WHERE "m_webhooks"."date_sent" = $1 AND "m_webhooks"."sending_ip" = $2 AND (m_webhooks.esp LIKE 'hotmail') AND (m_webhooks.event LIKE 'sent')
这似乎“date_sent”属性包含在所有查询中,这意味着 SQL 正在搜索每个查询的所有 1M 记录。
我已经阅读了十多篇关于提高 Rails 查询性能的文章,但我在其中发现的所有技巧都没有减少完成此方法所需的时间。提前感谢您提供任何见解。
m_webhooks.controller.rb
def index
def set_sub_count_hash(thip) {
gmail_hooks: {opened: a = thip.gmail.send(@event).size, total_sent: b = thip.gmail.sent.size, perc_opened: find_perc(a, b)},
hotmail_hooks: {opened: a = thip.hotmail.send(@event).size, total_sent: b = thip.hotmail.sent.size, perc_opened: find_perc(a, b)},
yahoo_hooks: {opened: a = thip.yahoo.send(@event).size, total_sent: b = thip.yahoo.sent.size, perc_opened: find_perc(a, b)},
other_hooks: {opened: a = thip.other.send(@event).size, total_sent: b = thip.other.sent.size, perc_opened: find_perc(a, b)},
}
end
@m_webhooks = MWebhook.select("date_sent", "sending_ip", "esp", "event", "email").all
@event = params[:event] || "unique_opened"
@m_list_of_ips = [#List of three ip addresses]
end_date = Date.today
start_date = Date.today - 10.days
date_range = (end_date - start_date).to_i
@count_array = []
date_range.times do |n|
this_date = end_date - n.days
@today_hooks = @m_webhooks.where(:date_sent => this_date)
@count_array[n] = {:this_date => this_date}
@m_list_of_ips.each_with_index do |ip, index|
thip = @today_hooks.where(:sending_ip => ip) #Stands for "Today Hooks ip"
@count_array[n][index] = set_sub_count_hash(thip)
end
end
【问题讨论】:
标签: ruby-on-rails postgresql rails-activerecord