1

Railsプログラムには、Products、Offerings、OfferingProducts、Ordersの4つのデータベースがあります。

サンプル提供:ミディアムキット

ミディアムキットには2つの製品が含まれています(これはOfferingProductデータベースで設定されます)1スモール2ミディアム

顧客は2つのミディアムキットを注文します

このプログラムは、この注文から2つの小と4つの中、および同様の多くの注文を説明する必要があります

商品を再注文できるように、毎週販売されている各商品の数を追跡する在庫システムを設定しようとしています。これを計算するために私は持っています:

def get_trend
  product = Product.first
  customer_orders =[]
  product.offerings.each do |o|
    customer_orders = customer_orders + o.orders
  end
  o=customer_orders.group_by { |t| t.date.beginning_of_week }
  y = []
  op=self.offering_products;
  o.sort.each do |week, orders|
    y << orders.map { |o| o.quantity*op.find_by_offering_id(o.offering).quantity }.sum
  end
  return y
end

これはうまくいくようですが、計算には約20秒かかります。これを速くする方法はありますか?私はほとんどの時間がによってかかることを知っています

y << orders.map { |o| o.quantity*op.find_by_offering_id(o.offering).quantity }.sum

特定の週に注文された製品の数を計算する行。何かご意見は?

4

2 に答える 2

1

問題は、宣言 (つまり、データベースへの結合) を使用したほうがよい場合に、反復 (つまり、アプリケーション コードのループ) を使用していることです。ループは決してジョインほど高速ではなく、データセットをアプリケーションのメモリに移動しても役に立ちません。

ActiveRecordを使用していると思いますか?もしそうなら、これは結合でクエリする方法に役立つかもしれません: http://guides.rubyonrails.org/active_record_querying.html

于 2012-05-30T00:37:01.533 に答える
1

これが、Iinからの情報のおかげで私がやったことです

def get_trend
    sql = ActiveRecord::Base.connection()
    if Rails.env == "production"
        d=sql.execute("SELECT SUM(orders.quantity * offering_products.quantity), EXTRACT(ISOYEAR FROM orders.date) AS year, EXTRACT(WEEK FROM orders.date) AS week " +
        " FROM orders " +
        " INNER JOIN offerings ON offerings.id = orders.offering_id " + 
        " INNER JOIN offering_products ON offering_products.offering_id = offerings.id " +
        " INNER JOIN products ON products.id = offering_products.product_id " +
        " WHERE (products.id = #{self.id}) GROUP BY year, week ORDER BY year, week ")
        y=d.map { |a| a["sum"].to_i }
    else
        d=sql.execute("SELECT SUM(orders.quantity * offering_products.quantity), strftime('%G-%V', orders.date) AS year " +
        " FROM orders " +
        " INNER JOIN offerings ON offerings.id = orders.offering_id " +
        " INNER JOIN offering_products ON offering_products.offering_id = offerings.id " + 
        " INNER JOIN products ON products.id = offering_products.product_id " +
        " WHERE (products.id = #{self.id}) GROUP BY year")
        y=d.map { |a| a[0] }
    end
    return y
end

更新: heroku は postgresql を使用し、日付関数の動作が異なるため、本番とローカルの間でコードを区別する必要がありました:( これは、関数が年の最初の週を異なる方法で処理するため、結果がまったく同じではないことも意味します。

于 2012-05-30T17:04:13.790 に答える