2011-09-04 23 views
1

我有1.8 millons行的項目表:如何提高PostgreSQL中OR或IN運算符的查詢性能?

Item 
----------- 
- id 
- title 
- content 
- channel_id 

和頻道表8000+行:

Channel 
----------- 
- id 
- name 

我需要的是顯示了一個名爲「全球」通道項目每結果,例如我有以下信道:

id | name 
________________ 
1  | global 
2  | restaurants 
3  | hotels 
... 

所以我曾嘗試以下諮詢誰:

SELECT * FROM Item WHERE channel_id = 1 OR channel_id = 2 ORDER BY title ASC LIMIT 10 
SELECT * FROM Item WHERE channel_id IN (1, 2) ORDER BY title ASC LIMIT 10 

他們都需要18秒! ...並已經有id的兩個指標和CHANNEL_ID

更新

看起來問題出在ORDER BY克勞斯,而不是OR或IN操作符,有太多的項目訂單。

更新 我有固定的這個標題爲創建索引:

CREATE INDEX item_by_title ON item (title ASC) 
+0

18秒對於只有2m左右的行非常緩慢(假設你沒有返回很多行,這可能會影響排序)。它運行得有多快,如果你只是做'WHERE channel_id = 1'?如果你刪除了'ORDER BY'子句? – NullUserException

+0

我剛試過。它需要17.5秒......我迷路了。一些建議? – zerofuxor

+0

所以'SELECT * FROM Item WHERE channel_id = 1'需要17.5秒?你實際返回多少行?我對pgSQL不太熟悉,但是如果你返回的行數超過5%左右,某些RDBMS將不會使用索引,而只是進行全表掃描。 – NullUserException

回答

1

通過按標題排序您強制爲1.8M元組最終排序步驟,只是爲了獲得前10名的記錄。 嘗試對id進行排序,例如。

+0

-1這是不正確的。在使用'ORDER BY'之前,使用'WHERE'進行過濾*。 – NullUserException

+0

那麼取決於有多少記錄通過過濾,我不知道他的數據。也許原始的海報可以顯示查詢計劃。或者在沒有ORDER BY子句的情況下測試他的查詢。 – wildplasser

+0

我刪除了downvote,但這看起來不太正確。如果查詢返回了180萬行,如果您對id或標題進行排序並不重要 – NullUserException