[英]How to reduce index scan time for a postgresql IN query with ordered results?
我構建了一個簡單的應用程序,用於使用rails和postgresql讀取RSS feed,但是當我嘗試在feed_entries
表中查詢來自多個feed的帖子時, feed_entries
性能問題。 查詢示例如下所示,以檢索給定的Feed ID集合的20個最新條目:
SELECT * FROM feed_entries WHERE feed_id IN (19, 21, 383, 1867, 3103) ORDER BY published_at DESC LIMIT 20;
feed_entries
表中包含約400萬行,並通過Fugu計划托管在Heroku Postgres上,並且具有一些索引,包括:
"index_feed_entries_on_feed_id_and_published_at" btree (feed_id, published_at)
"index_feed_entries_on_published_at" btree (published_at)
這是查詢計划程序的結果:
EXPLAIN ANALYZE SELECT * FROM feed_entries WHERE feed_id IN (19, 21, 383, 1867, 3103) ORDER BY published_at DESC LIMIT 20;
Limit (cost=4353.93..4353.94 rows=20 width=1016) (actual time=12172.275..12172.325 rows=20 loops=1)
-> Sort (cost=4353.93..4355.07 rows=2286 width=1016) (actual time=12172.268..12172.284 rows=20 loops=1)
Sort Key: published_at
Sort Method: top-N heapsort Memory: 52kB
-> Index Scan using index_feed_entries_on_feed_id_and_published_at on feed_entries (cost=0.00..4341.76 rows=2286 width=1016) (actual time=8.612..12169.504 rows=630 loops=1)
Index Cond: (feed_id = ANY ('{19,21,383,1867,3103}'::integer[]))
Total runtime: 12172.520 ms
規划器看起來好像正在使用適當的索引,但是掃描索引仍然需要約12秒的時間,這對具有400萬行的表來說太長了。 如果我完全按照上面的方式重復查詢計划器,那么第二次它告訴我整個過程僅花費2毫秒,這可能僅僅是因為第一個查詢的結果已被緩存,但是這仍然讓我感到困惑。 在運行查詢之前,我也嘗試運行VACUUM ANALYZE
,但差異不大。 另外,如果我在表中查詢單個feed_id,那么查詢計划者將Index Scan Backward using index_feed_entries_on_feed_id_and_published_at on feed_entries
,並且總執行時間要快得多,約為20ms。
我是否可以采用其他策略來優化此相對簡單的IN查詢的性能?
要嘗試的另一件事是這種替代查詢形式:
SELECT *
FROM feed_entries
JOIN (unnest('{19,21,383,1867,3103}'::int[]) AS feed_id) sub USING (feed_id)
ORDER BY published_at DESC
LIMIT 20;
但是,列的排序順序在多列索引中 確實很重要。 采用:
CREATE index_feed_entries_2 ON feed_entries (feed_id, published_at DESC)
如果根據該索引對表進行CLUSTER
,這可能會給您帶來一點點提升,但是有效性會隨着大量更新而降低。 閱讀此相關答案的最后一章以獲取更多信息:
位圖堆掃描性能
嘗試使用DESC順序創建索引。 例如。
create index feed_entries_published_at_desc_idx on feed_entries ( published_at desc ) with (fillfactor=100);
您可以在(feed_id,published_at desc)上嘗試與上述類似的(復合)索引,以查看其工作原理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.