Sql Postgres查询调优

Sql Postgres查询调优,sql,performance,postgresql,group-by,Sql,Performance,Postgresql,Group By,我有一张保存历史记录的桌子。每当更新计数时,都会添加一条记录,指定当时已获取新值。表架构如下所示: Column | Type | Modifiers ---------------+--------------------------+-------------------------------------------------------------------- id

我有一张保存历史记录的桌子。每当更新计数时,都会添加一条记录,指定当时已获取新值。表架构如下所示:

    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)。解释分析给出:

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天(如果不每天更新记录,则可以扫描更长时间)来加快查询速度:


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

尝试在
created::date
上创建索引,并在当前日期-7和当前日期之间添加where子句
where created::date
。顺便问一下:将
创建的
转换为时间戳的目的是什么?这已经是一个时间戳了。@一匹没有名字的马很有趣,我没有注意到我在做这个。我现在将索引添加到
created::date
WHERE
子句中,以检查这一点,并告诉我为什么
project\u accountrecord(created::date DESC)上创建索引
返回
ERROR:syntax ERROR at or near:::“
使用cast语法而不是::您需要将其放在paradensis:
在项目上创建索引\u accountrecord((created::date)DESC)。而且从带时区的时间戳到日期的转换不是“稳定的”,因此无法为该表达式编制索引。但是在
上创建的索引本身可能已经有所帮助了。
where created_date>now()::date-'7 days'::interval