2013-02-27 47 views
1

這是建立了另一個問題,多個左連接到每個返回單列,未完成

Left join and only last row from right

我在哪裏嘗試撰寫使用相同的策略,第二個連接。我在我的開發人員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添加LIMIT並不會改變任何內容。

感謝您的閱讀。

回答

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 
+0

非常好。快速,並且幫助我理解很有意義。謝謝! – 2013-02-27 20:52:45

+0

使用PostgreSQL'DISTINCT ON'可以簡化內部查詢。整個查詢可以更快。 – 2013-02-27 20:55:05

1

另一種方法查詢戈登·利諾夫寫道:

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 

可能(也可能不會)更快的數據。你必須測試它。

+0

不錯,在這個特殊情況下只需要一個實例的快速測試就給了我大約20%的提升。謝謝! – 2013-02-27 21:09:17