2013-03-01 37 views
2

最近我將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 

你會推薦什麼?

回答

1

如果searching_id#7646553行超過表的幾個百分比那麼該列上的索引將不會被用作表掃描會更快。做一個

select count(*) from mentions where searches_id = 7646553 

並比較總行數。

如果它們小於表中的百分之幾,然後嘗試

with m as (
    SELECT * 
    FROM mentions 
    WHERE searches_id = 7646553 
) 
select * 
from m 
order by id asc 

或者創建一個綜合指數:

create index index_name on mentions (searches_id, id) 

如果searches_id具有低cardinality然後創建相反的同一指標order

create index index_name on mentions (id, searches_id) 

analyze mentions 

創建索引後。

+0

@Pajak你嘗試我建議CTE? '用......' – 2013-03-01 13:15:55

+0

Thx尋求幫助。但是問題不在search_id#7646553。只有65行,表中提到的總行數爲150毫升。 當我解釋查詢選擇計數(*)從提及where searching_id = 7646553,它使用正確的索引sear_id。 我不想創建新的索引,因爲我認爲這些searches_id是要執行的正確索引。 – 2013-03-01 13:16:36

+0

現在我發現最好的解決方案是執行 set enable_indexscan = false;在運行查詢之前運行 ,查詢後切換爲true。它的工作原理,但它不是優雅的解決方案。 – 2013-03-01 13:16:58

0

對我來說,我有索引,但他們都是基於3列,我沒有叫出索引中的一列,所以它是在整個事情上進行seq掃描。可能的修復:更多的索引,但使用更少的列(和/或切換列順序)。

我們看到的另一個問題是我們有正確的索引,但顯然它是一個「無效」(創建不佳的CONCURRENT?)索引。所以放下它並創建它(或重新編譯它)並開始使用它。

What are the available options to identify and remove the invalid objects in Postgres (ex: corrupted indexes)

參見http://www.postgresql.org/docs/8.4/static/indexes-multicolumn.html