关于性能:如果PostgreSQL count(*)总是很慢,如何分页复杂查询?

If PostgreSQL count(*) is always slow how to paginate complex queries?

如果PostgreSQL的count(*)总是很慢,如何分页复杂查询?

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

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


您是否阅读了该文章的标题?

Note that the following article only applies to versions of PostgreSQL prior to 9.2. Index-only scans are now implemented.

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

也就是说,在较旧的版本上使用LIMITOFFSET通常可以正常工作。 如果您不介意任何变化,则可以使用表统计信息来估算行数(因此也可以估算页数)。 请参阅您已链接的文章中的"估计行数"。

无论如何,使用LIMITOFFSET进行分页都是一种反模式。 很多时候,您可以重新定义分页代码,以便它使用sort_column > 'last_seen_value' LIMIT 100,即避免偏移。 有时可能会导致很大的性能提升。


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

1
SELECT COUNT(*) FROM news;

26171

1
EXPLAIN ANALYZE SELECT COUNT(*) FROM news;

总运行时间:13.057毫秒

1
SELECT reltuples::BIGINT AS COUNT FROM pg_class WHERE oid = 'public.news'::regclass;

26171

1
EXPLAIN ANALYZE SELECT reltuples::BIGINT AS COUNT FROM pg_class WHERE oid = 'public.news'::regclass;

总运行时间:0.053毫秒