2013-10-01 152 views
1

我有一個表,包含歷史記錄。只要計數得到更新,就會添加一條記錄,指定當時取得新值。表格模式如下所示:Postgres查詢調整

Column  |   Type   |        Modifiers 
---------------+--------------------------+-------------------------------------------------------------------- 
id   | integer     | not null default nextval('project_accountrecord_id_seq'::regclass) 
user_id  | integer     | not null 
created  | timestamp with time zone | not null 
service  | character varying(200) | not null 
metric  | character varying(200) | not null 
value   | integer     | not null 

現在我希望獲得過去七天內每天更新的記錄總數。這是我想出的:

SELECT 
    created::timestamp::date as created_date, 
    count(created) 
FROM 
    project_accountrecord 
GROUP BY 
    created::timestamp::date 
ORDER BY 
    created_date DESC 
LIMIT 7; 

這運行緩慢(11406.347ms)。 EXPLAIN ANALYZE給出:

Limit (cost=440939.66..440939.70 rows=7 width=8) (actual time=24184.547..24370.715 rows=7 loops=1) 
    -> GroupAggregate (cost=440939.66..477990.56 rows=6711746 width=8) (actual time=24184.544..24370.699 rows=7 loops=1) 
     -> Sort (cost=440939.66..444340.97 rows=6802607 width=8) (actual time=24161.120..24276.205 rows=92413 loops=1) 
       Sort Key: (((created)::timestamp without time zone)::date) 
       Sort Method: external merge Disk: 146328kB 
       -> Seq Scan on project_accountrecord (cost=0.00..153671.43 rows=6802607 width=8) (actual time=0.017..10132.970 rows=6802607 loops=1) 
Total runtime: 24420.988 ms 

該表中有超過680萬行。我能做些什麼來提高此查詢的性能?理想情況下,我希望它在一秒鐘內運行,以便我可以將其緩存並每天在後臺更新一次。

+2

嘗試在'created :: date'上創建一個索引,並在current_date - 7和current_date之間添加where子句'where created :: date。順便說一句:將'created'轉換爲時間戳的目的是什麼?它*已*是一個時間戳。 –

+0

@a_horse_with_no_name有趣的我沒有注意到我正在那樣做。我將這個索引添加到'created :: date'和'WHERE'子句中來檢查 –

+0

在這裏打我,並告訴我爲什麼'在project_accountrecord上創建索引(created :: date DESC);'returns'ERROR :「::」處或附近的語法錯誤。 –

回答

2

現在,您的查詢必須掃描整個表格,計算結果並將其限制爲最近7天。 您可以通過掃描僅最近7天的加速比查詢(或更多,如果你不天天更新記錄):

where created_date>now()::date-'7 days'::interval 

另一種形式給出就是緩存在額外的表歷史結果只計算當前日期。