首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  PostgreSQL

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

  •  
  •   Livid · 41 天前 · 3320 次点击
    这是一个创建于 41 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    控制所有插入和删除的地方,有动作时在别的地方维护总数;或者隔一段时间跑一次。二选一吧。
        20
    nekoneko   40 天前
    只知道 mysql 的 myisam 引擎会把一张表的行数存起来,查的时候秒出
        21
    glacer   40 天前
    不需要实时精确数据的话,就是存缓存定时更新。
    还有一种做法就是取 Explain 的 rows。
        22
    starsriver   40 天前 via Android
    cache 阿,没见过这么统计的。
        23
    est   40 天前
    这事儿刚好也遇到过。楼上很多已经给出回答了,我具体说下,就是 EXPLAIN SELECT COUNT(id) FROM table 去看 rows 那一行返回。预估的。有误差。
        24
    lolizeppelin   14 天前
    @est 要加 where 过滤咋办 233333
        25
    est   14 天前
    @lolizeppelin 那就直接加上咯
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2155 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 20ms · UTC 06:24 · PVG 14:24 · LAX 23:24 · JFK 02:24
    ♥ Do have faith in what you're doing.