2013-06-03 9 views
1

我有一個有近100萬行的漂亮的大桌子,其中一些查詢的時間是long(超過一分鐘)。如何在Postgres中優化此SQL查詢?

這裏是一個多數民衆贊成讓我特別辛苦...

EXPLAIN ANALYZE SELECT "apps".* FROM "apps" WHERE "apps"."kind" = 'software' ORDER BY itunes_release_date DESC, rating_count DESC LIMIT 12; 
                  QUERY PLAN                
--------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=153823.03..153823.03 rows=12 width=2091) (actual time=162681.166..162681.194 rows=12 loops=1) 
    -> Sort (cost=153823.03..154234.66 rows=823260 width=2091) (actual time=162681.159..162681.169 rows=12 loops=1) 
     Sort Key: itunes_release_date, rating_count 
     Sort Method: top-N heapsort Memory: 48kB 
     -> Seq Scan on apps (cost=0.00..150048.41 rows=823260 width=2091) (actual time=0.718..161561.149 rows=808554 loops=1) 
       Filter: (kind = 'software'::text) 
Total runtime: 162682.143 ms 
(7 rows) 

所以,我將如何優化呢? PG版本是9.2.4,FWIW。

kindkind, itunes_release_date已經有索引。

+0

這並不回答你的問題,但如果你有100萬條記錄,你可能最好使用'apps'中的數字引用來創建一個'app_kind'表,而不是重複'varchars',比如''software''超過 –

+1

@LukasEder:或者他可以使用枚舉來保持現有查詢不變。 –

回答

3

看起來你缺少一個索引,例如在(kind, itunes_release_date desc, rating_count desc)

+1

'kind'索引可能就夠了嗎?不知道額外的列會加快排序。 – AngerClown

+0

@AngerClown'kind'上已有索引 – Shpigford

+0

kind上的索引可能很有用,但仍會產生top-n排序。要使用索引直接獲取前12名,OP將需要在索引中添加(所有)排序列。 –

0

apps表有多大?你至少有這麼多的內存分配給postgres?如果每次都必須從磁盤讀取數據,查詢速度會變慢。

另一件可能有用的事情是在'應用程序'列上對錶進行聚類。這可能會加速磁盤訪問,因爲所有software行將按順序存儲在磁盤上。

+0

由於查詢需要全面掃描和排序,因此羣集不會有所幫助。 Postgres內存分配可以幫助,但不是很多。 –

0

加快此查詢的唯一方法是在(itunes_release_date, rating_count)上創建一個複合索引。它將允許Postgres直接從索引中選取前N行。