提高 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 的性能的主要内容,如果未能解决你的问题,请参考以下文章