如果PostgreSQL count(*)总是很慢,那么如何对复杂查询进行分页?

Dan*_*kov 24 postgresql performance postgresql-9.1

如果PostgreSQL的count(*)始终慢怎么分页复杂的查询?

只要在这种情况下我们有很多页面(例如不同的类别,过滤器等),制作触发器似乎不是一个好的解决方案.

如果VACUUM/VACUUM ANALYZE/ANALYZE/VACUUM FULL没有帮助该怎么办?count(*)postgresql 使用的最佳实践是什么?

Cra*_*ger 18

你读过那篇文章的标题了吗?

请注意,以下文章仅适用于9.2之前的PostgreSQL版本.现在已实现仅索引扫描.

使用9.2,你通常会发现你得到了更好的结果.阅读仅索引扫描Wiki页面以获取详细信息.

也就是说,在旧版本上使用LIMIT并且OFFSET通常工作正常.如果您不介意一些变化,可以使用表统计信息估计行计数(以及页面计数).请参阅您已链接到的文章中的 "估算行数" .

无论如何,使用LIMIT和使用OFFSETIMO是一种反模式.很多时候你可以重新编写你的分页代码,以便它使用sort_column > 'last_seen_value' LIMIT 100,即它避免了偏移.这有时可以带来非常大的性能提升.

  • 刚刚升级到9.2.没有改变 (7认同)
  • @Daniil你已经联系到了答案; 只需阅读http://wiki.postgresql.org/wiki/Slow_Counting,"估算行数" (2认同)
  • 我也有同样的问题.即我需要对过滤结果进行分页.过滤器是各种用户定义的设置,即它具有"超过9000"的变化.因此缓存计数不是(可行的)选项.我在这里提出了查询和解释:https://gist.github.com/NoICE/59a915e4b2b522e574e8任何提示/帮助将不胜感激!:-) PS我不知道为什么添加连接(如在gist中看到的)产生如此可怕的性能下拉(因为它被索引,它不应该imo ...). (2认同)

小智 11

如果您正在执行SELECT count(*)FROM table并且启用了pg stats,则可以使用较低的示例,在这种情况下,从13ms到0.05ms.

SELECT count(*) FROM news;
Run Code Online (Sandbox Code Playgroud)

26171

EXPLAIN ANALYZE SELECT count(*) FROM news;
Run Code Online (Sandbox Code Playgroud)

总运行时间:13.057毫秒

SELECT reltuples::bigint AS count FROM pg_class WHERE oid = 'public.news'::regclass;
Run Code Online (Sandbox Code Playgroud)

26171

EXPLAIN ANALYZE SELECT reltuples::bigint AS count FROM pg_class WHERE oid = 'public.news'::regclass;
Run Code Online (Sandbox Code Playgroud)

总运行时间:0.053毫秒

  • 这两个查询给出了不同的结果. (6认同)
  • 如何添加像where子句这样的过滤器? (2认同)