如果PostgreSQL的count(*)
是always slow如何对复杂查询进行分页?
制作触发器似乎不是一个好的解决方案,只要在这种情况下我们有很多页面(例如不同的类别,过滤器等)。
如果VACUUM/VACUUM ANALYZE/ANALYZE/VACUUM FULL
没有帮助怎么办?将count(*)
与postgresql一起使用的最佳做法是什么?
答案 0 :(得分:18)
您是否阅读过该文章的标题?
请注意,以下文章仅适用于9.2之前的PostgreSQL版本。现在已实现仅索引扫描。
使用9.2,你会发现你会得到更好的结果。请阅读the index-only scans wiki page了解详情。
也就是说,使用LIMIT
和OFFSET
的旧版本通常可以正常工作。如果您不介意一些变化,可以使用表统计信息估计行计数(以及页面计数)。请参阅“估算行数”in the article you already linked to。
使用LIMIT
和OFFSET
进行分页,IMO,无论如何都是反模式。很多时候你可以改写你的分页代码,所以它使用sort_column > 'last_seen_value' LIMIT 100
,即它避免了偏移。这有时可以带来非常大的性能提升。
答案 1 :(得分:11)
如果你正在进行SELECT count(*)FROM table并且启用了pg stats,你可以使用较低的例子,在这种情况下从13ms下降到0.05ms。
SELECT count(*) FROM news;
26171
EXPLAIN ANALYZE SELECT count(*) FROM news;
总运行时间:13.057毫秒
SELECT reltuples::bigint AS count FROM pg_class WHERE oid = 'public.news'::regclass;
26171
EXPLAIN ANALYZE SELECT reltuples::bigint AS count FROM pg_class WHERE oid = 'public.news'::regclass;
总运行时间:0.053毫秒