2017-08-25 63 views
0

因此,我正在研究一个建筑物的轨道应用程序,该应用程序可以跟踪水的使用/收集和电力使用/太阳能发电等。这些存储为测量行,连接到传感器,这些传感器连接到程序建筑物,基本上)和亚型(附属于类型 - 水,电)。如何减少数据库调用时间和数量(Rails)?

我正在用chartkick做一些图表,而与此相关的数据库调用太慢了。在生产服务器上它们会更快,但是也会有更多的数据。

下面是有图表生成和数据库调用其中的helper方法:

def stackedSubtypeChart(grouping) 
rsubs = @resource.subtypes 
      .order(:usage?) #add usage types after gen types 
      .map{|stype| [ 
       stype.name,stype.measurements #this takes too long! 
       .where("date >= ?", params[:start]) #(4 calls!!) 
       .where("date <= ?", params[:stop]) 
       .group_by_period(grouping, :date).maximum(:amount)]} 

rsubs = rsubs.map {|stype| 
        {name: stype[0], 
        data: stype[1]}} 

ret = column_chart rsubs, 
        stacked: true, 
        library: { :series => {0 => { type: "line"}}} 
end 

@resource在控制器中定义为:

@resource = Type.includes(:subtypes => :sensors).find_by_resource('electricity') 

我评论说是负责任的行因为有多个电话,这绝对是问题的一部分。这需要两秒钟的时间加载我的(不可否认的是非常非常古老)的电脑与一个月的数据。

我真的可以在改变地图的时候使用帮助,以便这是一个调用,而不是多个子类型的调用,并且减少了我正在调用的内容,因此每个调用都不需要半秒。我没有很多优化这类事情的经验,我不知道如何开始做比我已经在这里更多。

回答

0

经过大量的攻击我的头撞墙后,我偶然发现,这是一个更快的单个查询,抓住所有我需要的数据+数据连接。格式化有点困难,但效果很好。

rsubs = Measurement 
      .where("measurements.date >= ? AND measurements.date <= ?", 
       offset(params[:start], -1, grouping), 
       offset(params[:stop], 1, grouping)) 
      .joins(sensor: {subtype: :type}) 
      .where("types.resource = ?", @rname) 
      .order('subtypes."usage?"') 
      .group_by_period(grouping, :date).group("subtypes.id, subtypes.name").maximum(:amount) 
0

可能有助于研究ActiveRecord Explain挖掘SQL。有一个很好的screencast,可以很好地解释(双关)。