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

分页查询,查个 total 很难吗?

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

    如题。一个破接口,后端开发人员三番五次说要不传 total,让我去别的地方取,说什么查个 total 相当全表扫,我真是服气。

    第 1 条附言  ·  139 天前

    认真阅读了各位的回复,感谢。

    1. 我自己确实不是专业后端开发者,知识有限,才会问出这个问题。
    2. 场景是:评论查询,app端展示,需要展示个总评论总数。
    3. 最后我们经过了友好的交流,索引+缓存足以解决问题(实时性需求不是很高)
    94 回复  |  直到 2018-04-10 19:17:12 +08:00
        1
    GaryZ   139 天前
    他不会建索引么 你去别的地方取 去哪取 去他家么?
        2
    kunluanbudang   139 天前 via Android
    后端水平不行

    楼主可以继续怼他
        3
    finab   139 天前
    √ 和他讲清楚,并提供相关文档给他查询 问题解决
    × 上 V 站抱怨 毫无用处
        4
    sagaxu   139 天前 via Android
    数据量大时查 total 是很慢的,不带条件 count 一次主键几十秒很正常
        5
    q364553873   139 天前 via Android
    lz count 一个千万级的表试试。。
        6
    banks0913   139 天前
    @q364553873 新人求学习。那这种情况一般有什么样的解决方案?
        7
    notreami   139 天前
    数据库性能都严重影响了,为啥不上 ES 呢?
        8
    annielong   139 天前
    大数据按条件分页查询再带 count 真的很麻烦,尤其是条件复杂的时候,优化都不好优化,只能跑两次查询,还特别慢
        9
    kera0a   139 天前
    @banks0913 我记得 MySQL 是有优化的,单纯的 count(*) 应该不是全表,速度很快的
        10
    GoLand   139 天前
    后端说的没毛病,能不用尽量不用 total。前端不用考虑啥性能问题,但是后端要考虑。
        11
    sagaxu   139 天前 via Android
    @kera0a 那是古代的 myisam 引擎,现代关系型 db,count 都很慢
        12
    neop   139 天前 via iPhone
    话说前端去哪里取 total
        13
    sxlzll   139 天前   ♥ 1
    1、可能很难,不了解数据量和存储不做评价
    2、楼主是前端,只需要站在用户和前端的角度思考,total 是不是必须的,如果是,后端就必须做,至于难的问题,什么事都那么简单那还要我们工程师干嘛
        14
    EmdeBoas   139 天前
    最近也是碰到了这个问题....5000W 的表...不带条件查 total 报警了....最后用 kylin 解决了,美滋滋
        15
    winglight2016   139 天前
    @EmdeBoas kylin,这个之前我也想用,但是没找到合适的场景,大佬再深入讲讲?
        16
    brickyang   139 天前 via iPhone   ♥ 1
    @banks0913 #6 可以维护一个字段,跟随增删 +/-1
        17
    lishunli   139 天前 via Android
    带 total 又要多查一次 db,要考虑量大性能问题什么。有总数就有可能查到最后一页,量大的话数据库查询最后几页还是很慢的。当然前提是数据多,如果就很少那无所谓了。
        18
    binux   139 天前 via Android
    这问题你去问 PM 啊,PM 说要做就做。
    然后再让 PM 找后端 estimate story points,看 PM 乐意给排期不。
    你操这个心干嘛。
        19
    hcymk2   139 天前
    @brickyang
    对有查询条件的这个字段有用么?
        20
    nigelvon   139 天前   ♥ 1
    不会做缓存?楼上说慢的我真是醉了,每次取数据都 count 一遍?
        21
    EmdeBoas   139 天前
    @winglight2016 kylin 就是做预计算的,支持百亿级数据查询毫秒出结果...一般查历史数据的时候好用,比如说今天 4-2 号,你只需要查 4-1 号以及之前的数据,就比较适用,每天写个定时任务,增量把前一天的数据预计算好给第二天用。kylin 搭起来跟维护的成本相当大的...
        22
    EmdeBoas   139 天前
    @nigelvon 然而查询条件会变,数据的量也可能在变
        23
    VincentWang   139 天前   ♥ 1
    @nigelvon 不太好缓存吧,即使不考虑数据库里的数据量在变化,查询条件也会变。
        24
    nigelvon   139 天前
    @EmdeBoas 数据变更不会更新缓存?查询条件组合多不会多设置几条缓存组合?
    恕我直言,连 total 都不愿意给的后端我不信数据多到 count 都慢的程度
        25
    linbiaye   139 天前   ♥ 1
    如果是 Mysql 的 InnoDB 的 count 不带 where 就是全表扫描,带了 where 看具体的 where,所以后端说的没毛病,表大了没有利用好索引或者没法利用索引就是很慢。
        26
    abusizhishen   139 天前 via Android
    他可以对指定来源屏蔽这个参数
        27
    EmdeBoas   139 天前
    @nigelvon .....我最近做的查询条件组合起来可能有上万种....做 count 多 9 秒起...
        28
    sagaxu   139 天前 via Android
    @nigelvon 查询条件的组合,数量是乘起来的,超过几十个的时候,更新缓存的成本会很高
        29
    nigelvon   139 天前
    @EmdeBoas 你这根本就不光是 count 的问题,连数据都查不出来,上搜索引擎。从楼主描述来看取数据没问题,那么 count 不存在简单方案解决不了的性能问题。
        30
    scnace   139 天前 via Android
    实时数据的 Count 真的很麻烦(耗性能) 分页那种 Case 的话 可以把 Total 拉到比较大 或者 同意楼上的维护单独表 count 的做法(鸟书也推荐这么做) P.S. es 并不是银弹 也要考虑到多个数据源的维护成本
        31
    eslizn   139 天前
    @nigelvon 取数据没问题不代表 count 没问题
        32
    EmdeBoas   139 天前   ♥ 3
    @nigelvon 老哥,你这根本不讲道理,你又不知道实际情况,你以为想用搜索引擎就用?都得结合自己组有的资源,解决方法有一万种,但更重要的是资源复用和可维护性
        33
    whypool   139 天前
    话说,数据量多的时候存自增 id,拿 max 会不会快点?
        34
    debuggerx   139 天前
    上个项目里有个查询,数据量大概在 300W 左右,每次都查出 count 的话还是比较影响性能的,查询一般在 1~3 秒,但是分析下来这个接口是一个下滑展示,而且没有提供转跳到某一页的功能,也就是说有用户死命地不停滑动也要一天才会请求到最后的数据,于是我专门给这个接口写了个分页查询,total 从 redis 里取,redis 里的值只在每天凌晨更新一次……
        35
    startar   139 天前 via Android
    如果后端是单纯的 db 的话,实时查 count 确实有可能很慢啊。一般都要扫索引。如果真要实时查就得预计算,上 kylin。
    建议对自己不熟悉的领域不要那么想当然。。
        36
    Socket   139 天前
    似曾相识,这玩意儿没 total 可不行,panigation 这种组件不传 total 没法展示页码,你只能点一下查一下,有就展示,没有就展示没数据
        37
    cheetah   139 天前
    哈哈看看豆瓣广播现在也没总页数
        38
    arslion   139 天前
    不讲清楚场景发这帖子干嘛?
        39
    wangbenjun5   139 天前
    说实话,那种几百上千万的数据表你们分页是给人看的吗?
        40
    wwdyy   139 天前
    那就跟产品说,后端说做不了分页,只能做下一页这样的
        41
    killerv   139 天前
    InnoDB 引擎的大表 count 确实慢,可以考虑缓存 count,插入和删除行的时候实时更新缓存。
        42
    nszm   139 天前
    @whypool #33 有个搜索条件
        43
    slime7   139 天前
    某绿帽论坛的查询会显示灰色页码,tooltip 提示可能有 xx 页,直到点到某页后没数据
        44
    ty89   139 天前
    不好说,这个得看业务情况具体分析,不过多数情况下用假分页就行了,比如微博的 timeline,不可能给你算 total 的
        45
    hadixlin   139 天前 via iPhone
    楼主的基础知识薄弱呀,这个 count 的问题可能是很复杂的优化,考虑成本来说,一般都是不做的
        46
    logOo   139 天前
    @wangbenjun5 嗯,你这个思路很好。
        47
    jadec0der   139 天前
    笑~很多时候前端开发表现的像普通用户一样。

    不知道你是多大的数据量,数据量大了以后 total 确实很难取,很多场景都是估算或者只给前面一部分结果,比如 Google 搜索,result 数量是估算的,翻页一般也只能翻几十页
        48
    panlilu   139 天前
    数据量大的情况查 total 是挺难的……
        49
    3a3Mp112   139 天前
    根本没说清楚这个 total 指的是什么数据,是每次请求回来的有效数量,还是什么?
        50
    w0000   139 天前
    数据大,有 where 条件,条件多并且组合也多的时候,是快不了的啊楼主
        51
    Immortal   139 天前
    其实看完描述我有几个问题和想法
    1、从别的地方取是哪里取?如果他这个接口里不好传,别的地方就能传了?
    2、这个应该不是全表扫,会走主键索引应该,都不会回表才是

    结果和楼上们说的一样,得看数据量才能决定,不是百万千万的 count 还是很快的,如果有连续主键都不用 count,取最大自增主键就好。以前我也经常和客户端吵这类问题,因为我发现他们没法理解服务端需要考虑的问题。归根结底还是没好好沟通,两边都有点责任,抽个时间和服务端聊下解决方案好了。具体服务端的优化方式楼上很多了。
        52
    MushishiXian   139 天前
    有时候 count 真的会挺慢的,加缓存你又要考虑各种查询条件,如果这个 total 不是特别重要,就真的没必要去 count
        53
    jydeng   139 天前
    total 确实很复杂,我们现在表数据量小的话,一般查询两次,一次查 total,一次分页查具体数据。
        54
    iyaozhen   139 天前 via Android
    抛开数据量和场景都是耍流氓
        55
    vincenttone   139 天前
    - 如果数据量大做了分表,恐怕后端就需要做个计数器(还不一定保证准确)。
    - 如果数据量小不做分表,多一次 IO。可以不扫全表,前提是有可用的索引。
        56
    sm0king   139 天前
    不管什么原因,该一个请求返回过来的数据,非要请求两条,还有,丢过来一堆数据让前端自己做数据处理对接的后台,都是偷懒。
        57
    play78   139 天前
    这个还是要根据实际业务来, 如果是必须的,那就提供呗。客户能接收等待时间,就多等几秒。
    如果业务中,不是必须的,就不用了。
    例如,查询记录类的数据。只要告诉用户有下一页就可以。不用提供总共有多少页。让用户一直下一页,下一页。
    又比如,一些动态排名之类的。可以后端起个定时任务,每 10 分钟更新一次数据。
    如果是要求实时类的,比如一些余额。那就必须要每次都统计了。
        58
    JamesPan   139 天前
    @kera0a myisam count 很快,innodb count 真的是扫全表,可以用 explain 得到的影响行来大致顶替 count
        59
    glues   139 天前
    ls 的某些高手很多啊,吹牛不要钱是吗?
        60
    Sunshow   139 天前
    是很难,没必要最好别用
        61
    weizhen199   139 天前
    有个办法,去统计信息里拿总行数,大致是精准的
        62
    toono   139 天前
    内心 OS: 他到底在说 MySQL 还是 MongoDB.....
        63
    tulongtou   139 天前
    @kera0a 问题是你不知道 where 后面有什么条件呢,所以没办法说 count(*) 快慢
        64
    tairan2006   139 天前
    真太大了就用 es/solr 查…
        65
    RTNelo   139 天前
    还好在我司没遇到过大表显示页号的需求,给前端传个 `is_end` 就行了
        66
    Immortal   139 天前
    @weizhen199
    这个的确可以,innodb 的查询优化器里应该有个大概数据用来做优化推算
        67
    chenqh   139 天前
    @weizhen199 不会拿。。
        68
    barbery   139 天前
    很烦这种分页,最完美的分页就是游标(逃
        69
    cysroad   139 天前
    如果一个表几百万的数据,一页 20 条,你显示个总页数有意思吗?分页带 total,一般只做 50 页以内的
        70
    kimmykuang   139 天前
    这个不是量大了都会遇到的问题么,简单就是做异构索引上 es,mysql innodb 千万各种条件 count,给个完美的方案?
        71
    icegreen   139 天前
    应该传 / 后端不行
        72
    icegreen   139 天前
    这种肯定是从用户 /产品设计的角度去出发, 第一要考虑的肯定是用户的体验和满足产品的需求;

    另外接口设计肯定是要为使用者服务和考虑的, 至少我们是这样要求的.
        73
    JKeita   139 天前
    不管你建不建索引,只要命中的数据量很大时,查 total 本来就很慢
        74
    finull   139 天前
    @debuggerx 这种不需要 total,某页如果是满页就认为有下一页就好
        75
    RubyJack   139 天前
    你看看淘宝网给不给你翻到最后一页?
    count 就是性能杀手,能不做就不做,后端没毛病。
        76
    wengjin456123   139 天前
    楼主没毛病啊,total 当然要给啊
        77
    nxtxiaolong   139 天前
    这个看数据库本身表中有没有存这个字段了,比如 mongodb 就每隔 collection 有这样的字段,没啥大问题,如果涉及到全表扫面,建立索引也是很慢的~
        78
    JKeita   139 天前
    数据量大就用 ES,才比较好解决
        79
    JKeita   139 天前
    还有即使是 ES 也会限制页数,页数越大查询越慢。所以数据量很大时,传 total 根本就毫无意义
        80
    maemual   139 天前
    如上面所说,我们不知道你们的业务场景到底是什么,上面动不动随便让人用 ES 的也都是随便瞎说。只能说的是,在某些场景下,取 count 可能确实是一个很麻烦的事情。所以希望能够对后端更加宽容,去了解为什么之后,好好的沟通。
        81
    jason19659   139 天前
    所以百万级的数据展示准确的 total 有什么意义。。数据少直接 count
        82
    dishuibaby   139 天前
    我们数据量比较大的时候。就用 solr 查询了。
    还有就是给前端用户的展现。通常展现的都固定条件的列表,也不需要展现所有的数据列表吧。应该也不会有很复杂的搜索让用户自己选择。如果查询条件真的复杂了,那就要借助其他工具了。solr es xunsearch 都可以把
    如果只是用 mysql 查,我们通常做的是最多展现 1000 页。
        83
    aliasliyu4   139 天前 via iPhone
    数据量很大的时候,我真的做不到啊,您继续喷吧,或者您来?
        84
    chairuosen   139 天前
    海量数据不是给人看的,给人看的拿 100 页足够
        85
    LichMscy   139 天前
    哈哈看标题第一反应没建索引,点进来果然
        86
    adablue77   139 天前
    如果你是前端 要明白自己职责是展现数据
    数据都不给你 展现个毛线啊
    性能优化不是你需要考虑的范围
    产品原型确实需要 total 值 就跟写接口的要去
    如果真是百万千万级的分页 你们后端会找产品撕逼的 不用你管
    以性能推脱 不给数据 那直接出静态页多好 保证快
        87
    jjx   139 天前
    搞 erp 的哭了


    每次报表必须有小计合计, 怎么也逃不过查询理论上执行了两次的命运
        88
    woshifyz   139 天前
    @nigelvon 你真写过大数据量的 count 吗?
        89
    yiplee   139 天前
    展示总评论总数查询条件不复杂性能肯定没问题
        90
    liuxu   139 天前
    需要建汇总表,《高性能 mysql 》一书建议可以用 Flexviews 插件
        91
    projectzoo   139 天前
    这个 count 确实不是简单的 count。。。
    一个 comment 表中查询某一条 news 的 comment count 真的不是简单得 select count(*) 这么搞。
        92
    jyf   138 天前
    count 确实慢 不过不给是不对的 我就是做后端的 后端不应该把自己的技术困难推给调用方 如果真的很慢 那就上缓存 告知不能达到很高实时性就可以了
        93
    petelin   138 天前
    700 万 700MB, 花了 1.59 秒
    6000 万 2.3G, count 不出来(已经没耐心等待返回了)
        94
    winglight2016   131 天前
    @EmdeBoas 那我是没机会用了,小厂完全用不上
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   实用小工具   ·   1177 人在线   最高记录 3762   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 27ms · UTC 16:53 · PVG 00:53 · LAX 09:53 · JFK 12:53
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1