【问题标题】:Do I need to rewrite this SQL query in Rails ActiveRecord?我需要在 Rails ActiveRecord 中重写这个 SQL 查询吗?
【发布时间】:2011-11-01 07:56:37
【问题描述】:

产品限时在网站上销售。

每次销售以DATE 开始,以DATE 结束,并且包含至少一种产品。

每个产品都与它所属的销售的 id# 相关联。

有时销售中没有产品的时间很短,因为经理创建了销售但尚未完成将产品与销售相关联,所以我必须在显示列表时过滤掉没有产品的销售即将到来的销售,否则会使用户感到困惑。

在我的Sale 模型中,我想出了这个,因为我对 ActiveRecord 不太熟悉:

def upcoming_sales
    find_by_sql(["SELECT DISTINCT sales.* from sales, products WHERE products.sale_id = sales.id AND sales.start_at > ? AND sales.start_at < ? ORDER BY sales.start_at ASC", Time.now, (Time.now + END_AT)])
end

我相信上面的 SQL 是标准的 ANSI SQL,应该可以在几乎任何数据库服务器上运行,但它可以用 ActiveRecord 代替吗?

除了使它对非 SQL 用户友好之外,用 ActiveRecord 重做它有什么好处吗?

在性能方面,哪种方式更好?

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord


    【解决方案1】:

    原始 SQL 难以维护。性能方面肯定原始 sql 更好,但请考虑ActiveRecord 的以下好处。你会得到一个很好的查询语法,考虑到其他人可能需要修改你的代码,它的可读性要高得多。此外,ActiveRecord 让您可以在一定程度上对数据库引擎不了解,这是使用原始 sql 无法实现的。

    但是,如果您将性能视为唯一的瓶颈,那么 ActiveRecord 就会落后。我会说,做一个小研究。上面的查询是一个连接查询,并且原始 SQL 绝对会给您带来显着的性能优势。可以做很多其他事情来显着提高查询的性能,比如正确的indexingcachingeager loading(当需要时,有时急切的加载实际上会使查询变慢)等等。在你放弃之前ActiveRecord确定,这确实是瓶颈。

    【讨论】:

      【解决方案2】:

      当然您可以编写自定义 SQL,但当 AR 工作正常时不建议这样做(您将获得同质清晰的代码、独立于数据库的...):

      def upcoming_sales
        select('DISTINCT sales.*').
          joins(:products).
          where(["sales.start_at > ? AND sales.start_at < ?", Time.now, Time.now + END_AT]).
          order("sales.start_at ASC")
      end
      

      【讨论】:

        猜你喜欢
        • 2011-12-11
        • 1970-01-01
        • 1970-01-01
        • 2015-04-07
        • 2017-07-26
        • 1970-01-01
        • 2013-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多