最近我將Postgresql從9.1升級到9.2版本。新計劃程序使用錯誤的索引並且查詢執行時間過長。Postgresql計劃器使用錯誤索引
查詢:
explain SELECT mentions.* FROM mentions WHERE (searches_id = 7646553) ORDER BY id ASC LIMIT 1000
解釋9.1版本:
Limit (cost=5762.99..5765.49 rows=1000 width=184)
-> Sort (cost=5762.99..5842.38 rows=31755 width=184)
Sort Key: id
-> Index Scan using mentions_searches_id_idx on mentions (cost=0.00..4021.90 rows=31755 width=184)
Index Cond: (searches_id = 7646553)
Expain在9.2版本:
Limit (cost=0.00..450245.54 rows=1000 width=244)
-> Index Scan using mentions_pk on mentions (cost=0.00..110469543.02 rows=245354 width=244
Index Cond: (id > 0)"
Filter: (searches_id = 7646553)
正確的做法是在9.1版本中,在那裏策劃者採用指數searches_id。在9.2版本規劃器中,不會使用該索引並通過sear_id過濾行。
當我在沒有ORDER BY id的情況下執行9.2版本查詢時,planner使用了searchable_id上的索引,但我需要按ID排序。
我也嘗試在子查詢中選擇行並在第二個查詢中對其進行排序,但是解釋顯示,規劃器與正常查詢中的行爲相同。
select * from (
SELECT mentions.* FROM mentions WHERE (searches_id = 7646553))
AS q1
order by id asc
你會推薦什麼?
@Pajak你嘗試我建議CTE? '用......' – 2013-03-01 13:15:55
Thx尋求幫助。但是問題不在search_id#7646553。只有65行,表中提到的總行數爲150毫升。 當我解釋查詢選擇計數(*)從提及where searching_id = 7646553,它使用正確的索引sear_id。 我不想創建新的索引,因爲我認爲這些searches_id是要執行的正確索引。 – 2013-03-01 13:16:36
現在我發現最好的解決方案是執行 set enable_indexscan = false;在運行查詢之前運行 ,查詢後切換爲true。它的工作原理,但它不是優雅的解決方案。 – 2013-03-01 13:16:58