2010-07-01 63 views
5

高級:我能做到這一點order bygroup by基於sum 任何更快嗎? (PG 8.4,FWIW,在非小桌子....認爲O(百萬行))算法改進

假設我有一個像這樣的表:

        Table "public.summary" 
    Column |  Type  |      Modifiers 
-------------+-------------------+------------------------------------------------------ 
ts   | integer   | not null default nextval('summary_ts_seq'::regclass) 
field1  | character varying | not null 
otherfield | character varying | not null 
country  | character varying | not null 
lookups  | integer   | not null 


Indexes: 
    "summary_pk" PRIMARY KEY, btree (ts, field1, otherfield, country) 
    "ix_summary_country" btree (country) 
    "ix_summary_field1" btree (field1) 
    "ix_summary_otherfield" btree (otherfield) 
    "ix_summary_ts" btree (ts) 

而且我想查詢:

select summary.field1, 
    summary.country, 
    summary.ts, 
    sum(summary.lookups) as lookups, 
from summary 
where summary.country = 'za' and 
    summary.ts = 1275177600 
group by summary.field1, summary.country, summary.ts 
order by summary.ts, lookups desc, summary.field1 
limit 100; 

(英文:前100字段1的在特定(TS,國家),其中 'topness' 是查找的任何匹配行的總和 ,不管的otherfield值)

什麼東西我真的可以加快這個速度嗎?算法 這似乎是一個全表掃描的東西,但我可能會錯過一些東西。

+0

+1:格式良好,並使用序列填充pk! – 2010-07-01 21:40:16

+1

'LIMIT 100'意味着只有100行將被返回,而不是每個ts/country /等的前100名。 – 2010-07-01 21:42:56

+0

格式化提示爲SO,記得把它全部寫成小寫,奇怪的是:) – 2010-07-02 13:46:27

回答

1

爲了能夠建議任何內容,您應該發佈查詢的執行計劃。

而「OMG Ponies」是正確的:限制100將限制整個結果爲100行,它不適用於單個組!

有一個在Postgres的維基一個很好的文章,解釋如何發佈與慢速查詢一個問題:

http://wiki.postgresql.org/wiki/SlowQueryQuestions

+0

我已更正問題以反映OMG Ponies點。他們是正確的,但這是正確的查詢,我想要的。我已更新文字以匹配。 – 2010-07-02 00:27:50

2

此查詢任何查詢計劃將不得不掃描每個匹配的行WHERE條件,按分組條件進行滾動 - 也就是說,工作量與組的輸入行數成正比,而不是結果行的數量。

對於像這樣的查詢可能的最有效的查詢計劃是單個索引掃描。如果您按照(國家,地區)的順序建立索引,這應該是可能的;使用該索引,此表單的每個可能查詢都會解析爲索引的連續範圍。儘管如此,這仍然需要內存中的排序 - 有可能避免使用不同的索引。

正如其他人所說,但發佈執行計劃是您的最佳選擇。

1

(country,ts)上的索引是最好的選擇(就像Nick Johnson所建議的那樣),另外如果它沒有設置的話,你可能想要提高work_mem。如果需要,你可以在運行時設置它(如果設置得非常高,那麼推薦)。這將有助於保持你的排序內存,而不是泄漏到磁盤(如果發生這種情況)。

對於真正的幫助,我們需要看到一個EXPLAIN ANALYZE,發佈在explain.depesz.com可以使它非常可讀。