Ruby on rails 查询和加速-图表的日期序列
下面的查询运行得相当快,但随后需要进行的系列处理确实减慢了此方法的速度。我需要一些重构方面的帮助Ruby on rails 查询和加速-图表的日期序列,ruby-on-rails,activerecord,series,Ruby On Rails,Activerecord,Series,下面的查询运行得相当快,但随后需要进行的系列处理确实减慢了此方法的速度。我需要一些重构方面的帮助 def self.sum_amount_chart_series(start_time) orders_by_day = Widget.archived.not_void. where(:print_datetime => start_time.beginning_of_day..Time.zone.now.end_of_day).
def self.sum_amount_chart_series(start_time)
orders_by_day = Widget.archived.not_void.
where(:print_datetime => start_time.beginning_of_day..Time.zone.now.end_of_day).
group(pg_print_date_group).
select("#{pg_print_date_group} as print_date, sum(amount) as total_amount")
# THIS IS WHAT IS SLOWING THE METHOD DOWN!
(start_time.to_date..Date.today).map do |date|
order = orders_by_day.detect { |order| order.print_date.to_date == date }
order && order.total_amount.to_f.round(2) || 0.0
end
end
def self.pg_print_date_group
"CAST((print_datetime + interval '#{tz_offset_hours} hours') AS date)"
end
我已经对这个方法进行了基准测试,有问题的代码是series循环,它在其中生成一系列日期,然后映射出一个新数组,其中包含每个日期的数量。通过这种方式,我可以得到一个序列,其中包含每个日期的金额,不管它是否有金额
当查询只返回几个日期时,它运行得相当快。但是,如果将开始日期推迟一两年,那么它的速度将变得极其缓慢。真正的罪犯是侦查方法。扫描activerecord对象数组的速度非常慢
是否有更快的方法生成此系列?订单按日期按“打印日期组”分组,因此它应该是对象的“日期”散列。那你为什么不这么做呢
(start_time.to_date..Date.today).map do |date|
order = orders_by_day[date.to_s(:db)]
order && order.total_amount.to_f.round(2) || 0.0
end
这将大大降低你跑步的难度。如果我误解了,你的订单不是散列,那么先将其预处理成散列,然后运行映射,你肯定不想检测每个日期 orders\u by\u day按“pg\u print\u date\u group”分组,因此它应该是对象的“date”散列。那你为什么不这么做呢
(start_time.to_date..Date.today).map do |date|
order = orders_by_day[date.to_s(:db)]
order && order.total_amount.to_f.round(2) || 0.0
end
这将大大降低你跑步的难度。如果我误解了,你的订单不是散列,那么先将其预处理成散列,然后运行映射,你肯定不想检测每个日期 由于代码中的主犯是必须一次又一次扫描数组的检测方法,因此我建议您颠倒创建序列的顺序,以便只扫描数组一次,并且代码在O(n)时间内运行 尝试以下几点: series = [] next_date = start_time.to_date orders_by_day.each do |order| while order.print_date.to_date < next_date series << 0.0 next_date = next_date.next end series << order.total_amount.to_f.round(2) next_date += 1 end while next_date < Date.today series << 0.0 next_date = next_date.next end 系列=[] 下一个日期=开始时间到日期 逐日订购。每个人都要订购| 而order.print_date.to_date