1

これは別の質問に基づいています。

左結合と右からの最後の行のみ

同じ戦略を使用して2番目の結合を作成しようとする場所。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;

だから私がこれでやろうとしているのは、最新の編集と最新のコメントですべての投稿を引っ張ることです。私のDBには約6000の投稿があり、投稿ごとに約100のコメントがあり、投稿ごとにおそらく10の編集があります.

ここで、両方ではなくいずれか一方を使用してクエリを実行すると、クエリは非常に高速に実行されます (1 分未満で、思ったほど速くはありません)。しかし、上記のようにクエリを実行すると、postgres は SSD の残りの 14 GB を処理し、約 5 分後に終了します。

なぜこれが起こるのか、誰か説明できますか?PARTITION BY 句に関する私の理解不足だと思います。結合されたテーブルを SELECT 句から削除し、サブクエリと外部クエリの両方に LIMIT を追加しても、何も変わりませんでした。

読んでくれてありがとう。

4

2 に答える 2

1

問題はおそらく、1 つの投稿 ID 内でデカルト積を取得していることです。たとえば、100 件の編集と 100 件のコメントがある場合、結合により 10,000 行になります。

解決策はrow_number()、サブクエリで実行することです。

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 に答える