2012-11-08 68 views
4

在我的應用程序中,我有一個主題回覆表。其結構大致如下:如何使用與簡單獲取N個結果不同的LIMIT子句?

CREATE TABLE responses (
    id INT NOT NULL PRIMARY KEY, 
    topic_id INT NOT NULL, 
    author_id INT NOT NULL, 
    response TEXT 
); 

id是一個自動遞增字段,topic_idauthor_id外鍵,也有相應的指標等

我總是想通過插入時間訂購,通常最近。在大多數情況下,我將通過topic_id進行過濾。一個典型的查詢看起來是這樣的:

SELECT * FROM responses WHERE topic_id=123 ORDER BY id DESC LIMIT 20; 
-- or, for pagination: 
SELECT * FROM responses WHERE topic_id=123 AND id < 456789 ORDER BY id DESC LIMIT 20; 

我想要實現阻止列表 - 每個用戶有author_id就是他們不希望看到一個列表。我需要檢索前20個結果,排除那些author_id s 以及回覆他們的回覆。確定一個行是否應該排除是非常複雜的,雖然它可能會在數據庫中執行(PL/SQL或預處理),但我希望將邏輯保留在應用程序中。所以我可以做以下兩件事之一:

  1. 忘記LIMIT子句,使查詢不受限制。直到我計算了20個有效結果爲止,然後關閉查詢。
  2. 應用分塊 - 指定LIMIT 40,並希望它足以獲得20個「好」結果。如果不是,則取下40個等等。

這兩者之間的實際區別是什麼? ESP。在許多併發用戶的性能方面。

我在PostgreSQL中這樣做,但我願意切換到不同的RDBMS。 (我不想失去引用完整性,所以我沒有考慮NoSQL解決方案)也許我不得不調整數據庫的某些參數(例如預取大小),以充分利用無界查詢情況?

+0

這並不直接回答你的問題,但出於好奇,你的數據模型中定義瞭如何「回覆他們的回覆」?如果您真的關心性能,最好讓數據庫完成它的工作,並讓索引工作來過濾數據。 –

+0

數據模型沒有定義它 - 它涉及解析「reply」標籤和用戶名的響應文本。一行可以包含對多個其他行的回覆,以及多個用戶的提及。一行也可以是部分回覆/回覆和部分獨立內容 - 在這種情況下,我想要做一些啓發式猜測並隱藏部分或全部行。 我可以對此進行預處理並創建1:n響應 - 回覆關係和1:n響應 - 關於提及的作者,這可能是一個足夠好的數據模型。 – matejcik

+0

至於性能方面,現在「分塊」方法已經足夠好了,我主要想知道在性能和便利性方面取消LIMIT子句是否是一個很好的折衷。 – matejcik

回答

1

在SQL中添加塊列表並不困難。

SELECT * FROM responses 
WHERE topic_id=123 
    AND author_id NOT IN (SELECT author_id FROM blocked WHERE user_id = X) 
ORDER BY id DESC LIMIT 20; 

只需添加一個NOT IN到您的WHERE子句。

如果你有一些理由,你不能做到這一點,那麼你的大塊的想法是最好的。您不希望沒有限制,因爲那麼數據庫會將所有內容都返回給查詢它的客戶端或服務器。

3

我不能說Postgres的具體情況,但查詢優化器可能會使用LIMIT子句作爲各種不同執行計劃的成本計算的一部分。

如果您...

select ... from ... where ... limit n 

那麼優化器知道你只是要檢索n行,但...

select ... from ... where ... 

優化器可能會認爲你想要的整個結果集,可能估計有幾千行。

特別是我期望RDBMS支持應用LIMIT子句的基於索引的訪問方法。

相關問題