高效的数据库查询Rails

时间:2014-02-05 07:44:20

标签: sql ruby-on-rails activerecord ruby-on-rails-4 rails-postgresql

我正在使用Rails 4和PostgreSQL,我有一个表格Quotes随机填充。有时两个条目相隔毫秒,有时是几小时(交易日结束)。我想建立一个过去1年的报价图表。

现在我正在使用

quotes = Quote.where(:created_at => 1.year.ago.beginning_of_day..Time.now.end_of_day).select(:price, :created_at)

这很有效,但我不需要(或想要)具有毫秒精度的所有数据。我想每隔1小时轮询一次数据库,但是我不确定如何构造查询。我当然可以从数据库中获取所有引用,然后解析它们并丢弃最多,但这似乎浪费了资源和时间。

另外,如果这似乎是从数据库获取报价的极其低效的方式,请告诉我。另请注意,数据库服务器是在主从配置中设置的,这些引用来自从属的读取请求。

1 个答案:

答案 0 :(得分:0)

我不知道这是否是最好的解决方案,我还没有完全对它进行基准测试,但我想我会把它放在那里,以便在类似的情况下帮助其他人。如果这不是一个格式正确的查询,请纠正我。

def get_quotes_3months(stock_symbol)    
    @results = []
        ActiveRecord::Base.connection.select_all(
            ActiveRecord::Base.send(:sanitize_sql_array, ["
            select price, created_at, symbol
            from (
                select price, created_at, symbol,
                       row_number() over (partition by date_trunc('hour', created_at) order by created_at) as r
                from quotes
                ) as dt
            where r = 1 AND created_at BETWEEN current_timestamp - INTERVAL '3 month' AND current_timestamp AND symbol = ?;", stock_symbol]
        )).each do |record|

            @results << {price: record["price"], created_at: record["created_at"].to_datetime}
        end
    return @results
end

基本上我按小时将表分组为组,然后按created_at对每个组进行排序,并获取每组中的第一行。我还清理了查询,因为输入将来自javascript ajax请求(在此步骤之前已经过清理,但我建立了冗余以防万一)。

最后要弄清楚的是如何将分区更改为按其他时间范围分组(即如果我每15分钟需要一个引号,则调用date_trunc('15分钟',created_at)没有意义。