我有一个特定的要求,允许用户下载整个月的记录。这可以包括15,000到20,000个记录的范围。我有一个优化的查询,但问题是在HTML渲染中。基本上,它会遍历每个记录并按时间,日期,速度等格式化。现在问题是在html打印窗口上实际呈现带有内容的表需要花费6分钟。如果我不能再优化查询或渲染,我还有其他选择吗? (注意没有必要将页面保存为缓存,因为每月只会下载一次这么大量的记录)
#query
@reports = unit.reports.where("reports.time > ? and reports.time < ?",range.begin, range.end)
@reports = @reports.includes(:alerts)
#view rendering:
- @reports.each do |r|
%tr
%td.num_col #{Report.index_of(@reports, r)}
- if @history_date
%td.time_col #{time_format(r.time)}
- else
%td.time_col #{datetime_format(r.time)}
- if @unit.unit_type.name == "MarineTrac"
%td.latitude_col #{r.latitude.to_s}
%td.longitude_col #{r.longitude.to_s}
%td.address_col{:title => r.address_formatted} #{r.address_formatted(:street => false)}
- else
%td.street_col{:title => r.street} #{r.street}
%td.speed_col #{speed_formatted(r)}
%td.distance_col #{r.distance}
- if r.alerts.any?
%td.alert_col
%ul{:style => "margin: 0px; padding: 0px; list-style-type: none;"}
- r.alerts.each do |alert|
%li
%span{:class => "#{alert.class_for_severity}"}= alert_full_str(alert)
- else
%td.alerts_col{:class => "severity_none"} None
%td.signal_col #{r.signal_formatted}
%td.fix_col #{r.gps_valid_str}
答案 0 :(得分:2)
我建议将报告生成提取到后台进程中。
基本上,使用Sidekiq之类的内容将用户请求时生成的报告排入队列。然后,您可以立即返回并告诉他们“您的报告现在正在生成。您将在完成后收到电子邮件。”
您的Sidekiq工作人员将完成所有工作,并在完成后向用户发送电子邮件。
答案 1 :(得分:1)
使用分页将结果拆分为可管理的块,我更喜欢Kaminari。
我怀疑你将需要在一个页面上获得所有结果。要处理此问题,您可以使用分页和jQuery infinite scroll在用户向下滚动页面时加载更多结果。这不仅可以加快初始页面加载速度,而且如果用户只查找第一批结果,它将减轻服务器上的压力,同时保持一页上列出所有内容。
即使无法选择滚动加载,您仍然可以使用ajax一次加载每个分页“页面”(每页2,000个结果?)。或者取决于您的服务器有多强大以及您需要多快的结果,您可以异步生成所有必需的ajax页面加载
答案 2 :(得分:0)
将其导出为可下载的CSV格式。
答案 3 :(得分:0)
答案 4 :(得分:0)