2016-09-18 37 views
2

我有一個非常簡單的,PostgreSQL的查詢檢索最新的50個新聞文章:最有效的方法來檢索相關數據行:子查詢,或單獨的查詢與GROUP BY?

SELECT id, headline, author_name, body 
FROM news 
ORDER BY publish_date DESC 
LIMIT 50 

現在我也想檢索每一篇文章的最新10條評論爲好。我能想到的兩種方式來完成檢索它們,我不知道哪一個是最好的PostgreSQL中的背景:


選項1:

直接做一個子查詢中的註釋原來的查詢,並把結果到一個數組:

SELECT headline, author_name, body, 
    ARRAY(
    SELECT id, message, author_name, 
    FROM news_comments 
    WHERE news_id = n.id 
    ORDER BY DATE DESC 
    LIMIT 10 
) AS comments 
FROM news n 
ORDER BY publish_date DESC 
LIMIT 50 

顯然,在這種情況下,應用程序邏輯就需要知道哪個索引數組中的是列,那也沒問題。

的一個問題,我與法看,就是不知道查詢規劃將如何執行它。這會有效地變成51個查詢嗎?


選項2:

使用原來非常簡單的查詢:

SELECT id, headline, author_name, body 
FROM news 
ORDER BY publish_date DESC 
LIMIT 50 

然後通過應用邏輯,收集所有新聞的id和使用那些在一個單獨的查詢,ROW_NUMBER ()將不得不在這裏使用,以限制每個新聞報道的結果數:

SELECT * 
FROM (
    SELECT *, 
     row_number() OVER(
      PARTITION BY author_id 
      ORDER BY author_id DESC 
     ) AS rn 
    FROM (
     SELECT * 
      FROM news_comment 
      WHERE news_id IN(123, 456, 789) 
    ) s 
) s 
where rn <= 10 

這種做法顯然更爲複雜,我不知道這是否會需要檢索爲範圍的新聞文章首先意見,然後砍掉那些其中行計數大於10


哪個選項是最好的?還是有更好的解決方案,我忽略了?

對於上下文來說,這是我自己開發的新聞聚合器網站,目前我有大約40,000篇新聞文章,有大約500,000條評論,所以我正在尋找最佳解決方案來幫助我保持增長。

+2

查看爲這兩組查詢生成的查詢計劃,然後決定 – Rahul

+1

我同意@Rahul。您需要查看查詢計劃,因爲答案可能很大程度上取決於可用的索引。詢問數據庫它打算做什麼,即查看查詢計劃,然後決定哪個計劃看起來更好,或者是否可以通過其他方式改進它。 – Andreas

+1

唯一可行的方法是:使用'explain analyze'檢查執行計劃 –

回答

3

您應該研究使用至少EXPLAIN ANALYZE您的語句的執行計劃。這將爲您提供優化程序在執行語句本身時所選擇的計劃,並且還會返回實際運行時間和其他統計信息。

另一種解決方案是使用LATERAL子查詢再次檢索不同行各新聞10條評論,但之後 - 你需要調查和比較計劃,選擇適合您的最佳方法:

SELECT 
    n.id, n.headline, n.uathor_name, n.body, 
    c.id, c.message, c.author_name 
FROM news n 
LEFT JOIN LATERAL ( 
    SELECT id, message, author_name 
    FROM news_comments nc 
    WHERE n.id = nc.news_id 
    ORDER BY nc.date DESC 
    LIMIT 10 
) c ON TRUE 
ORDER BY publish_date DESC 
LIMIT 50 

當您的查詢包含使用WHERE子句的連接評價從新聞橫向檢索到的每一行LATERAL交叉引用。因此,使其成爲重複執行並加入從您的源表中的每行中檢索的信息新聞

這種方法將節省處理陣列從選項1出來,而不必發佈每個新聞許多單獨的查詢,如在選項2節省您(在這種情況下)需要爲您的應用程序邏輯的時間打開單獨的事務,建立連接,檢索行等等所需的時間...

通過創建索引並查找計劃程序成本常量和計劃程序方法配置參數,您可以嘗試瞭解選擇策劃者已經做出。更多關於這個問題here

+0

我在所有選項上運行了EXPLAIN ANALYSE,JOIN LATERAL是迄今爲止在使用正確索引的2000萬條記錄測試中最快的。 –