1

我的 rails 程序中有 4 个数据库,产品、产品、产品和订单

样品供应:中型套件

中型套件包含 2 种产品(在 OfferingProduct db 中设置) 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

多亏了 Iain 的信息,这就是我最终所做的

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 回答