6

这里和那里(包括 postgres web 上的官方帖子)有一些关于慢计数(*)之前版本 9.2 的讨论;不知何故,我没有找到满意的答案。

基本上我安装了 postgres 9.1,我观察到慢计数(*)很简单

select count(*) from restaurants;

在记录超过 100k 的表上。平均请求约为850ms。好吧,我假设这是人们一直在谈论的关于 postgres 9.1 及以下版本的缓慢计数的症状,因为 postgres 9.2 具有一些新功能,例如index-only scan。我想通过使用 9.1 中的相同数据集进行实验并将其放在 9.2 上。我调用了 count 语句,它仍然给出了 9.1 的错误结果。

explain analyze select count(*) from restaurants;
------------------------------------------------------------------
Aggregate  (cost=23510.35..23510.36 rows=1 width=0) (actual time=979.960..979.961 rows=1 loops=1)
   ->  Seq Scan on restaurants  (cost=0.00..23214.88 rows=118188 width=0) (actual time=0.050..845.097 rows=118188 loops=1)
 Total runtime: 980.037 ms

任何人都可以提出可行的解决方案来解决这个问题吗?我需要在 postgres 上配置任何东西来启用该功能吗?

PS where 子句对我的情况也无济于事。

4

2 回答 2

2

See the index only scans wiki entries:

In particular, I quote:

It is important to realise that the planner is concerned with minimising the total cost of the query. With databases, the cost of I/O typically dominates. For that reason, "count(*) without any predicate" queries will only use an index-only scan if the index is significantly smaller than its table. This typically only happens when the table's row width is much wider than some indexes'.

See also the discussion of VACUUM and ANALYZE for maintaining the visibility map. Essentially, you probably want to make VACUUM more aggressive, and you'll want to manually VACUUM ANALYZE the table after you first load it.

于 2012-12-13T07:58:17.603 回答
0

这是由于 PostgreSQL 的 MVCC 实现而发生的。简而言之,为了对表行进行计数,PostgreSQL 需要确保它们存在。但是鉴于每条记录的多个快照/版本,PostgreSQL 无法直接汇总整个表。因此,PostgreSQL 读取每一行,执行顺序扫描。!

如何解决这个问题?

有不同的方法可以解决这个问题,包括基于触发器的机制。如果您可以使用估计的行数,您可以检查 PostgreSQL pg_class reltuples:

    SELECT reltuples::BIGINT AS estimate FROM pg_class WHERE relname=<table_name>

复数:

[它是] 表中的行数。这只是规划者使用的估计值。— PostgreSQL:文档:pg_class

更多信息:

https://medium.com/@vinicius_edipo/handling-slow-counting-with-elixir-postgresql-f5ff47f3d5b9

http://www.varlena.com/GeneralBits/120.php

https://www.postgresql.org/docs/current/static/catalog-pg-class.html

于 2018-04-04T00:42:45.803 回答