优化Ruby-on-Rails查询

优化Ruby-on-Rails查询,ruby-on-rails,ruby,postgresql,Ruby On Rails,Ruby,Postgresql,我正在制作一个仪表板,以显示测量结果的图表。我很难用Rails高效/快速地处理这些数据(6) 它的5个图表(温度、湿度…)都显示了相同时间跨度的数据,在中,每个图表都是平均值、最小值和最大值。因此,页面上总共有15个数据集 每个测量(记录)有五列(温度、湿度…)具有不同的测量读数。图形的测量量可以在+-3000条记录到100.000条记录之间变化。这些测量值按月分组。然后计算最小、最大和平均数据集。因此,所有这15个数据集都基于相同的记录 我的想法是从数据库中加载一次测量值并对其执行计算。因此,

我正在制作一个仪表板,以显示测量结果的图表。我很难用Rails高效/快速地处理这些数据(6)

它的5个图表(温度、湿度…)都显示了相同时间跨度的数据,在中,每个图表都是平均值、最小值和最大值。因此,页面上总共有15个数据集

每个测量(记录)有五列(温度、湿度…)具有不同的测量读数。图形的测量量可以在+-3000条记录到100.000条记录之间变化。这些测量值按月分组。然后计算最小、最大和平均数据集。因此,所有这15个数据集都基于相同的记录

我的想法是从数据库中加载一次测量值并对其执行计算。因此,我不必查询每个数据集的数据。在从数据库查询度量值时,我使用Groupdate gem()将度量值按月快速分组。然后,我可以每月平均,最低和最高

不幸的是,每次计算我都会得到一个查询。这会使页面加载变慢。。知道如何优化数据库中的加载度量吗?之后我可以集中精力对代码进行折射

def dashboard_device
    @device = Device.find(params[:id])
    @last_measurement = @device.measurements.last
    @weather_forecast_location = @device.sublocation.location
    start_date = Date.parse('1-1-2020')
    end_date = Date.parse('31-12-2020')

    selected_measurements = @device.measurements.select(:measurement_date, :moisture, :temperature, :dielectricity, :conductivity, :salinity).group_by_month(:measurement_date, range: start_date..end_date, format: '%B')

    @moisture = selected_measurements.average(:moisture).compact
    @moisture_max = selected_measurements.maximum(:moisture).compact
    @moisture_min = selected_measurements.minimum(:moisture).compact

    @temperature = selected_measurements.average(:temperature).compact
    @temperature_max = selected_measurements.maximum(:temperature).compact
    @temperature_min = selected_measurements.minimum(:temperature).compact

    @dielectricity = selected_measurements.average(:dielectricity).compact
    @dielectricity_max = selected_measurements.maximum(:dielectricity).compact
    @dielectricity_min = selected_measurements.minimum(:dielectricity).compact

    @conductivity = selected_measurements.average(:conductivity).compact
    @conductivity_max = selected_measurements.maximum(:conductivity).compact
    @conductivity_min = selected_measurements.minimum(:conductivity).compact

    @salinity = selected_measurements.average(:salinity).compact
    @salinity_max = selected_measurements.maximum(:salinity).compact
    @salinity_min = selected_measurements.minimum(:salinity).compact

    render 'dashboard'
  end
更新

使用Pull似乎有效,但不幸的是,我没有得到数据对应的月份

将控制器更改为

selected_measurements = @device.measurements.select(:measurement_date, :moisture, :temperature, :dielectricity, :conductivity, :salinity).group_by_month(:measurement_date, range: start_date..end_date, format: '%B')

    result = selected_measurements.select('MAX(moisture)', 'AVG(moisture)', 'MIN(moisture)')
似乎很接近,但它给出了一个错误:

PG::GroupingError: ERROR: column "measurements.measurement_date" must appear in the GROUP BY clause or be used in an aggregate function

您可以使用自定义select语句执行此操作

@moisture = selected_measurements.average(:moisture).compact
@moisture_max = selected_measurements.maximum(:moisture).compact
@moisture_min = selected_measurements.minimum(:moisture).compact
就像这样

result = selected_measurements.select("MAX(moisture) as max_moisture, AVG(moisture), MIN(moisture)")
result.first.max_moisture
如果你只需要这些价值观的话,也可以用勇气

result = selected_measurements.pluck("MAX(moisture), AVG(moisture), MIN(moisture)")

您可以使用自定义select语句执行此操作

@moisture = selected_measurements.average(:moisture).compact
@moisture_max = selected_measurements.maximum(:moisture).compact
@moisture_min = selected_measurements.minimum(:moisture).compact
就像这样

result = selected_measurements.select("MAX(moisture) as max_moisture, AVG(moisture), MIN(moisture)")
result.first.max_moisture
如果你只需要这些价值观的话,也可以用勇气

result = selected_measurements.pluck("MAX(moisture), AVG(moisture), MIN(moisture)")

您应该在数据库中选择聚合,而不是在Ruby中进行数字运算。您可以选择带有字符串的骨料
。选择('AVG(湿度)作为AVG\u moissure')
。或者使用Arel
Measurement.Arel\u table[:weather].average.as('avg\u moissure')
。如果定期查询相同的聚合,请创建一个SQL视图或一个包含通过运行cron选项卡生成的月度聚合的表。这是来自某个gem的
groupby\u month
您应该在数据库中选择聚合,而不是在Ruby中进行数字运算。您可以选择带有字符串的骨料
。选择('AVG(湿度)作为AVG\u moissure')
。或者使用Arel
Measurement.Arel\u table[:weather].average.as('avg\u moissure')
。如果定期查询相同的聚合,请创建一个SQL视图或一个包含通过运行cron选项卡生成的月度聚合的表。这是来自某个gem的
groupby\u month