一个关于 SELECT COUNT(id) 的初级问题

2019-08-12 13:25:28 +08:00
 Livid

发现像下面这样的查询,希望获得一张表里的记录总数,在表的数据量比较大(上亿)的情况下,PostgreSQL 是无法马上返回结果的,需要等几十秒。有什么更好的方法么?

SELECT COUNT(id) FROM table
7563 次点击
所在节点    PostgreSQL
26 条回复
myyou
2019-08-12 13:28:22 +08:00
上亿的话分表的,对每个表进行 count 汇总不知道会不会快一点
Hermann
2019-08-12 13:28:29 +08:00
pg_class
ipwx
2019-08-12 13:28:31 +08:00
count(1) count(*) 这两种写法的耗时呢?
lihongming
2019-08-12 13:29:24 +08:00
理论上 COUNT(*)更快,因为 COUNT(id)要检查有没有 id,id 为 null 的不计数,而*不检查
df4VW
2019-08-12 13:30:48 +08:00
@ipwx postgres 的话,count(*) 更快
itskingname
2019-08-12 13:31:11 +08:00
@lihongming 如果 id 是主键的话,它就不会检查了吧。
rio
2019-08-12 13:34:21 +08:00
df4VW
2019-08-12 13:37:12 +08:00
@rio 这里面说的其实都有点过时,现在都是 redis 里放一份就都解决了
zeraba
2019-08-12 13:43:51 +08:00
看需求,如果这个值必须并且需要精确计算,定期统计后存聚合以后的值,或者插入就更新都是可选方案,如果是估算,可以直接用估算值,当然也可以估算之后再精确算
wph95
2019-08-12 13:49:07 +08:00
如果只是想知道一张表里的记录总数,用 pg_class 里的 reltuples 是最快的 常量级别。EXPLAIN 用的就是这个参数,开销极小。但是这个值存在误差的可能。
想要精准结果 count(*) 最快
rio
2019-08-12 13:53:50 +08:00
@df4VW 放 redis 的话一致性问题怎么解决?当然要看具体场景对数据准确性和可用性的要求。
kingwl
2019-08-12 14:21:13 +08:00
@ipwx
我记得是一样的 这个 case 在列裁剪的时候大概能干掉
gz911122
2019-08-12 14:21:39 +08:00
EXPLAIN 取结果,不过有误差
Raymon111111
2019-08-12 14:27:50 +08:00
需要精准的数据就离线跑吧
x7395759
2019-08-12 14:39:38 +08:00
4 楼的说法是正确的,不过是 mysql 里的,至于 PostgreSQL 是不是也是一样的,我猜是一样的
razertory
2019-08-12 14:43:53 +08:00
大多数关系型数据库的存储引擎都是行存,做精准行数统计的时候多数是很慢的。如果说不需要精准那么用一些自带的函数可以改善。还有就是可以考虑用列存储引擎,或者用 Redis 做个 counter。
oatw
2019-08-12 14:58:06 +08:00
额,如果只是要统计一个表里的记录数量,是不是可以在写入数据的时候就把数量+1,在 Rails 里好像就是这么处理的,说的不对不要打我,我只是个小前端来 drop the beat。。。
Mazexal
2019-08-12 15:17:35 +08:00
我觉得如果不是要精确数据的话, 可以每隔一分钟跑一次任务, 然后缓存起来, 每次就获取最近的一次就好了
Muninn
2019-08-12 16:06:24 +08:00
一般来说需要的都不是精确数据,那就再专门做一个低精度的缓存就好。

控制所有插入和删除的地方,有动作时在别的地方维护总数;或者隔一段时间跑一次。二选一吧。
nekoneko
2019-08-12 16:08:54 +08:00
只知道 mysql 的 myisam 引擎会把一张表的行数存起来,查的时候秒出

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/591160

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX