我們的PostgreSQL數據庫包含以下表:PostgreSQL的速度很慢索引掃描
類別
id SERIAL PRIMARY KEY name TEXT
文章
id SERIAL PRIMARY KEY content TEXT
categories_articles(多對一對多的關係)
條category_id INT REFERENCES categories (id) article_id INT REFERENCES articles (id) UNIQUE (category_id, article_id)
評論
article_id INT REFERENCES articles (id) posted_date TIMESTAMP NOT NULL is_visible BOOLEAN NOT NULL is_banned BOOLEAN NOT NULL message TEXT
我們對comments
表有部分指數:
CREATE INDEX comments_posted_date_idx
ON comments USING btree (posted_date)
WHERE is_visible = TRUE AND is_banned = FALSE;
因此,我們需要通過類來獲得最近的評論:
SELECT * FROM comments co
JOIN categories_articles ca
ON ca.article_id = co.article_id
WHERE ca.category_id = 1
AND co.is_visible = TRUE
AND co.is_banned = FALSE
ORDER BY co.posted_date DESC
LIMIT 20;
EXPLAIN ANALYZE
輸出:
Limit (cost=0.00..1445.20 rows=20 width=24) (actual time=93969.479..98515.109 rows=20 loops=1)
-> Nested Loop (cost=0.00..7577979.47 rows=104871 width=24) (actual time=93969.475..98515.084 rows=20 loops=1)
-> Index Scan Backward using comments_posted_date_idx on comments co (cost=0.00..3248957.69 rows=9282514 width=40) (actual time=13.405..82860.852 rows=117881 loops=1)
-> Index Scan using categories_articles_article_id_idx on categories_articles ca (cost=0.00..0.45 rows=1 width=16) (actual time=0.132..0.132 rows=0 loops=117881)
Index Cond: (article_id = co.article_id)
Filter: (category_id = 1)
Total runtime: 98515.179 ms
有什麼辦法優化查詢?
UPD:表comments
有約1100萬行。
您的統計信息可能爲開啓。嘗試'真空分析評論;'首先。 – wildplasser
這通常是避免*的更好方法。嘗試寫出cols。 – PeterRing
另外,您可能需要在聯結表上創建_reversed_索引:'在categories_article(article_id,category_id)上創建唯一索引'另外:通過正確的統計信息和調優,我期望此查詢產生散列計劃。 – wildplasser