关于sql:Postgres查询调优

Postgres Query Tuning

我有一张包含历史记录的表格。 每当计数更新时,都会添加一条记录,指定此时获取新值。 表模式如下所示:

1
2
3
4
5
6
7
8
    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

现在我想获得过去七天每天更新的记录总数。 这是我想出的:

1
2
3
4
5
6
7
8
9
10
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给出:

1
2
3
4
5
6
7
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万行。 我该怎么做才能提高此查询的性能? 理想情况下,我希望它能在一秒钟内运行,因此我可以将其缓存并在后台每天更新几次。


现在,您的查询必须扫描整个表,计算结果并限制为最近7天。
您可以通过仅扫描过去7天(或更多,如果您不每天更新记录)来加速查询:

1
WHERE created_date>now()::date-'7 days'::INTERVAL

另一种方法是将历史结果缓存在额外的表中,并仅计算当前日期。