提高 postgres 的性能

Posted

技术标签:

【中文标题】提高 postgres 的性能【英文标题】:improve performance for postgres 【发布时间】:2020-05-29 10:38:03 【问题描述】:

我这样统计用户数,运行5秒出结果,我正在寻找更好的解决方案

SELECT COUNT(*)
FROM (SELECT user_id
      FROM slot_result_primary
      WHERE session_timestamp BETWEEN 1590598800000 AND 1590685199999
      GROUP BY user_id) AS foo

【问题讨论】:

edit您的问题并添加使用explain (analyze, buffers, format text)生成的execution plan(不是只是一个“简单”解释)为formatted text,并确保您防止缩进计划。粘贴文本,然后将``` 放在计划前一行和计划后一行。还请包括所有索引的完整 create index 语句。 【参考方案1】:

首先你可以简化查询:

SELECT COUNT(DISTINCT user_id)
FROM slot_result_primary
WHERE session_timestamp BETWEEN 1590598800000 AND 1590685199999

最重要的是 - 确保您有 关于 sesion_timestamp 的索引

【讨论】:

谢谢,我试过了,但效果并不好 试过什么?在 session_timestamp 上放置索引?你的表有多少行? 请为您的查询发布 EXPLAIN ANALYZE 输出。 我运行了这个命令 CREATE INDEX session_timestamp_index ON slot_result_primary (session_timestamp) 并再次查询该表有10998516行 您需要在索引中包含 user_id 以使其更快【参考方案2】:

在 Postgres 中计数是一项非常繁重的操作。如果可能的话,应该避免。 很难让它变得更好,所以对于每一行 Postgress 都需要去光盘。您确实可以创建一个更好的索引来更快地选择从磁盘中选择哪些行,但即使有了这个计数时间,与数据大小相比,它也总是会在线性时间内及时增加。

你的索引应该是:

CREATE INDEX session_timestamp_user_id_index ON slot_result_primary (session_timestamp, user_id)

为了最好的结果。

索引仍然不能完全解决您的计数问题。在我两天前遇到的类似情况(SELECT 查询运行 3s 和 count 运行 1 秒)专用索引允许将选择时间缩短到 0.3 毫秒,但我能用 count 做的最好是 700 毫秒。

在这里您可以找到一篇很好的文章,其中总结了为什么计数很困难以及改善计数的不同方法: https://www.citusdata.com/blog/2016/10/12/count-performance/

【讨论】:

您还应该包括要使用此建议索引的查询。这是上面@Milney 建议的查询的错误索引。

以上是关于提高 postgres 的性能的主要内容,如果未能解决你的问题,请参考以下文章

提高 RODBC-Postgres 写入性能

结合关系查询提高 Postgres jsonb 查询的性能

postgres 截断很慢

Postgres 8.3 中的位图扫描比索引扫描 Postgres 9.4 快 2 倍?

如何提高我的 Postgres 选择语句的速度?

提高查询速度:大 postgres 表中的简单 SELECT