我有入我存儲的「會話」記錄的PostgreSQL表。這些會話有時會很快創建(有時會達到幾百秒)。我顯然不能讓桌子無限增長。所以我有一個守護進程,它週期性地掃描表格,強加一個外部可配置的大小限制。清潔最古老的最大行數
當記錄數超過限制時,我想抽出最早的記錄(使用限制值),將它們以文本形式寫入單獨的(非關係)日誌文件,然後從表中刪除它們。我現在正在做的工作,但有一個很高的限制,它是非常緩慢的。我當前的查詢是這樣的:
SELECT * FROM sessions ORDER BY modified DESC OFFSET 1000000 LIMIT 10000;
我的程序然後記錄那些最近最少修改的記錄到離線的歷史,然後做一個單獨的SQL DELETE
砸行。問題是,如果我說1000010記錄需要25-30秒的順序才能獲得這10條記錄,那麼執行上面的查詢。在modified
字段上創建索引似乎沒有任何明顯的影響,所以我假設postgres在它計算出前100萬條記錄之前創建了一個臨時數據集,然後排除它們。
是否有更好的方法來做到這一點,以獲得相同的結果?我基本上只想獲得表中最早的「count(*) - N
」行。
(現在我知道我可以先做一個獨立的查詢來獲取表的count(*)
,然後反向查詢的ORDER BY
條款,然後只用LIMIT
但這似乎缺憾。這將是我的備用,但我更喜歡做什麼我上面直接如果可能的話說明。)
1)你能在你的查詢運行'EXPLAIN'以確定是否PostgreSQL的實際打你創建的索引? 2)您是否願意選擇「修改」在給定時間戳之前的所有記錄?這__可以更好地找到索引。 –
因此,事實證明,我過分簡化了我的例子。這個問題比我想象的要多(我忽略了上面的WHERE子句,儘管我沒有認爲它是相關的,但事實證明這是至關重要的)。感謝@AndrewRueckert提供運行EXPLAIN的建議。我從中學到了很多東西(它需要連續掃描等等),並且基本上按照您的建議進行:首先使用SELECT來確定參考時間戳,然後使用反向SELECT來查找比時間戳更早的行。新流量加上索引後,典型情況下降至幾秒鐘。 –