【问题标题】:Rails SQL query optimizationRails SQL 查询优化
【发布时间】:2012-09-12 13:42:50
【问题描述】:

我的网站上有一个特色部分,其中包含三种类型的特色帖子:普通、大和小。目前我正在三个单独的查询中获取这三种类型,如下所示:

@featured_big_first = Post.visible.where(pinged: 1).where('overlay_type =?', :big).limit(1)
@featured_big_first = Post.visible.where(pinged: 1).where('overlay_type =?', :small).limit(1)
@featured_big_first = Post.visible.where(pinged: 1).where('overlay_type =?', :normal).limit(5)

基本上,我正在寻找一个将这三者合二为一并获取 1 个大帖子、1 个小帖子和 5 个普通帖子的查询。

【问题讨论】:

    标签: sql ruby-on-rails optimization join


    【解决方案1】:

    如果您不想要订单,我会感到惊讶。正如你所拥有的,它应该找到一个随机小、随机大和 5 个随机正态。

    是的,您可以使用 UNION。但是,您必须执行 SQL。查看三个查询中每一个的 SQL 日志,并执行一个字符串的执行 SQL,该字符串是三个查询中的每一个,中间有 UNION。它可能会起作用,或者它可能有限制问题。

    在 SQL 中可以通过将表连接到自身,对表的其中一个别名执行 group by,当另一个别名表为

    因此,如果您对 posts 表有一个简单的查询(没有可见和 ping 条件)并且想要最新 created_at 日期的记录,那么正常查询将是:

    SELECT posts1.*
    FROM posts posts1, posts posts2
    WHERE posts2.created_at >= posts1.create_at
      AND posts1.overlay_type = 'normal'
      AND posts2.overlay_type = 'normal'
    GROUP BY posts1.id
    HAVING count(posts2.id) <= 5
    

    使用这个 SQL,并添加可见和 ping 的条件,记住对帖子 1 和帖子 2 都使用条件。

    然后把大版本和小版本写在一起,UNION一下。

    我会坚持使用三个数据库调用。

    【讨论】:

      【解决方案2】:

      我认为这是不可能的,但您可以使用scope,这是编写代码的更多 Rails 方式

      也可能只是拼写错误,但您正在重新分配 @featured_big_first,因此它将仅包含最后一个查询的数据

      在 post.rb 中

        scope :overlay_type_record lamda{|type| joins(:visible).where(["visible.pinged=1 AND visible.overlay_type =", type])}
      

      在控制器中

      @featured_big_first = Post.overlay_type_record(:big).limit(1)
      @featured_small_first = Post.overlay_type_record(:small).limit(1)
      @featured_normal_first = Post.overlay_type_record(:normal).limit(5)
      

      【讨论】:

      • 谢谢建议,我会执行的。在接受您的回答之前,我会稍等片刻,b/c 我相信使用 UNION 的自定义 sql 查询是可能的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2014-02-04
      • 2014-11-16
      • 2011-06-22
      相关资源
      最近更新 更多