1

这是建立另一个问题,

左连接,只有右数的最后一行

我尝试使用相同的策略组成第二个连接。我在我的 dev macbook pro 上运行 postgres 9.1.4。在此处查看此简化示例:

SELECT * FROM (
    SELECT 
      post.*,
      comment.*,
      edit.*,
      ROW_NUMBER() OVER (PARTITION BY post.id ORDER BY edit.date_applied DESC) AS rna,
      ROW_NUMBER() OVER (PARTITION BY post.id ORDER BY comment.date_posted DESC) AS rnb
    FROM 
      post
    LEFT JOIN edit
      ON     post.id = edit.post_id
    LEFT JOIN comment
      ON     post.id = comment.post_id
    ORDER BY
      post.id DESC
) AS q
WHERE rna = 1 AND rnb = 1;

所以我想要做的是提取所有帖子,包括最新的编辑和最新的评论。在我的数据库中,大约有 6000 个帖子,每个帖子大约 100 条评论,每个帖子可能有 10 个编辑。

现在,如果我使用其中一个联接而不是两者都运行查询,则查询运行得非常快(不到一分钟,没有我想要的那么快)。但是,如果我按照上面介绍的方式运行查询,postgres 会浏览我 SSD 上剩余的 14 GB,并在大约 5 分钟后放弃。

谁能解释为什么会发生这种情况?我希望这是我对 PARTITION BY 子句缺乏了解。从 SELECT 子句中删除连接的表并在子查询和外部查询中添加 LIMIT 没有任何改变。

谢谢阅读。

4

2 回答 2

1

问题可能是您在一个帖子 ID 中获得了笛卡尔积。例如,如果您有 100 条编辑和 100 条评论,那么由于加入,您最终将有 10,000 行。

解决方案是执行row_number()in 子查询:

SELECT post.*, comment.*, edit.*
FROM 
  post
LEFT JOIN (select e.*,
                  ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY e.date_applied DESC) AS rna
           from edit e
           ) edit
  ON     post.id = edit.post_id and rna = 1
LEFT JOIN (select c.*,
                  ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY c.date_posted DESC) AS rnb
           from comment c
          ) comment
  ON     post.id = comment.post_id and rnb = 1
ORDER BY
  post.id DESC
于 2013-02-27T19:59:29.780 回答
1

另一种查询方式 Gordon Linoff 写道:

SELECT post.*, comment.*, edit.*
FROM 
  post
LEFT JOIN (SELECT DISTINCT ON (e.post_id) e.*                  
           FROM edit e
           ORDER BY e.post_id DESC, e.date_applied DESC
           ) edit
  ON     post.id = edit.post_id
LEFT JOIN (SELECT DISTINCT ON (c.post_id) c.*
           FROM comment c
           ORDER BY c.post_id DESC, c.date_posted DESC
          ) comment
  ON     post.id = comment.post_id
ORDER BY
  post.id DESC

它可能(或可能不会)更快地处理您的数据。你必须测试它。

于 2013-02-27T21:00:32.983 回答