如题。一个破接口,后端开发人员三番五次说要不传 total,让我去别的地方取,说什么查个 total 相当全表扫,我真是服气。
认真阅读了各位的回复,感谢。
1
GaryZ 2018-04-02 12:31:35 +08:00
他不会建索引么 你去别的地方取 去哪取 去他家么?
|
2
kunluanbudang 2018-04-02 12:34:18 +08:00 via Android
后端水平不行
楼主可以继续怼他 |
3
finab 2018-04-02 12:35:51 +08:00
√ 和他讲清楚,并提供相关文档给他查询 问题解决
× 上 V 站抱怨 毫无用处 |
4
sagaxu 2018-04-02 12:37:58 +08:00 via Android
数据量大时查 total 是很慢的,不带条件 count 一次主键几十秒很正常
|
5
q364553873 2018-04-02 12:38:33 +08:00 via Android
lz count 一个千万级的表试试。。
|
6
banks0913 2018-04-02 12:42:49 +08:00
@q364553873 新人求学习。那这种情况一般有什么样的解决方案?
|
7
notreami 2018-04-02 12:44:41 +08:00
数据库性能都严重影响了,为啥不上 ES 呢?
|
8
annielong 2018-04-02 12:45:56 +08:00
大数据按条件分页查询再带 count 真的很麻烦,尤其是条件复杂的时候,优化都不好优化,只能跑两次查询,还特别慢
|
10
GoLand 2018-04-02 12:47:09 +08:00
后端说的没毛病,能不用尽量不用 total。前端不用考虑啥性能问题,但是后端要考虑。
|
12
neop 2018-04-02 12:52:30 +08:00 via iPhone
话说前端去哪里取 total
|
13
sxlzll 2018-04-02 13:02:53 +08:00 1
1、可能很难,不了解数据量和存储不做评价
2、楼主是前端,只需要站在用户和前端的角度思考,total 是不是必须的,如果是,后端就必须做,至于难的问题,什么事都那么简单那还要我们工程师干嘛 |
14
EmdeBoas 2018-04-02 13:03:56 +08:00
最近也是碰到了这个问题....5000W 的表...不带条件查 total 报警了....最后用 kylin 解决了,美滋滋
|
15
winglight2016 2018-04-02 13:08:03 +08:00
@EmdeBoas kylin,这个之前我也想用,但是没找到合适的场景,大佬再深入讲讲?
|
17
lishunli 2018-04-02 13:09:54 +08:00 via Android
带 total 又要多查一次 db,要考虑量大性能问题什么。有总数就有可能查到最后一页,量大的话数据库查询最后几页还是很慢的。当然前提是数据多,如果就很少那无所谓了。
|
18
binux 2018-04-02 13:12:21 +08:00 via Android
这问题你去问 PM 啊,PM 说要做就做。
然后再让 PM 找后端 estimate story points,看 PM 乐意给排期不。 你操这个心干嘛。 |
20
nigelvon 2018-04-02 13:15:35 +08:00 1
不会做缓存?楼上说慢的我真是醉了,每次取数据都 count 一遍?
|
21
EmdeBoas 2018-04-02 13:17:34 +08:00
@winglight2016 kylin 就是做预计算的,支持百亿级数据查询毫秒出结果...一般查历史数据的时候好用,比如说今天 4-2 号,你只需要查 4-1 号以及之前的数据,就比较适用,每天写个定时任务,增量把前一天的数据预计算好给第二天用。kylin 搭起来跟维护的成本相当大的...
|
23
VincentWang 2018-04-02 13:20:35 +08:00 1
@nigelvon 不太好缓存吧,即使不考虑数据库里的数据量在变化,查询条件也会变。
|
24
nigelvon 2018-04-02 13:20:49 +08:00
@EmdeBoas 数据变更不会更新缓存?查询条件组合多不会多设置几条缓存组合?
恕我直言,连 total 都不愿意给的后端我不信数据多到 count 都慢的程度 |
25
linbiaye 2018-04-02 13:20:50 +08:00 1
如果是 Mysql 的 InnoDB 的 count 不带 where 就是全表扫描,带了 where 看具体的 where,所以后端说的没毛病,表大了没有利用好索引或者没法利用索引就是很慢。
|
26
abusizhishen 2018-04-02 13:22:32 +08:00 via Android
他可以对指定来源屏蔽这个参数
|
29
nigelvon 2018-04-02 13:28:15 +08:00
@EmdeBoas 你这根本就不光是 count 的问题,连数据都查不出来,上搜索引擎。从楼主描述来看取数据没问题,那么 count 不存在简单方案解决不了的性能问题。
|
30
scnace 2018-04-02 13:32:00 +08:00 via Android
实时数据的 Count 真的很麻烦(耗性能) 分页那种 Case 的话 可以把 Total 拉到比较大 或者 同意楼上的维护单独表 count 的做法(鸟书也推荐这么做) P.S. es 并不是银弹 也要考虑到多个数据源的维护成本
|
32
EmdeBoas 2018-04-02 13:34:44 +08:00 3
@nigelvon 老哥,你这根本不讲道理,你又不知道实际情况,你以为想用搜索引擎就用?都得结合自己组有的资源,解决方法有一万种,但更重要的是资源复用和可维护性
|
33
whypool 2018-04-02 13:35:59 +08:00
话说,数据量多的时候存自增 id,拿 max 会不会快点?
|
34
debuggerx 2018-04-02 13:36:27 +08:00
上个项目里有个查询,数据量大概在 300W 左右,每次都查出 count 的话还是比较影响性能的,查询一般在 1~3 秒,但是分析下来这个接口是一个下滑展示,而且没有提供转跳到某一页的功能,也就是说有用户死命地不停滑动也要一天才会请求到最后的数据,于是我专门给这个接口写了个分页查询,total 从 redis 里取,redis 里的值只在每天凌晨更新一次……
|
35
startar 2018-04-02 13:38:26 +08:00 via Android
如果后端是单纯的 db 的话,实时查 count 确实有可能很慢啊。一般都要扫索引。如果真要实时查就得预计算,上 kylin。
建议对自己不熟悉的领域不要那么想当然。。 |
36
Socket 2018-04-02 13:41:40 +08:00
似曾相识,这玩意儿没 total 可不行,panigation 这种组件不传 total 没法展示页码,你只能点一下查一下,有就展示,没有就展示没数据
|
37
cheetah 2018-04-02 13:47:46 +08:00
哈哈看看豆瓣广播现在也没总页数
|
38
arslion 2018-04-02 13:49:20 +08:00
不讲清楚场景发这帖子干嘛?
|
39
wangbenjun5 2018-04-02 13:49:22 +08:00
说实话,那种几百上千万的数据表你们分页是给人看的吗?
|
40
wwdyy 2018-04-02 13:51:27 +08:00
那就跟产品说,后端说做不了分页,只能做下一页这样的
|
41
killerv 2018-04-02 13:53:44 +08:00
InnoDB 引擎的大表 count 确实慢,可以考虑缓存 count,插入和删除行的时候实时更新缓存。
|
43
slime7 2018-04-02 13:55:37 +08:00
某绿帽论坛的查询会显示灰色页码,tooltip 提示可能有 xx 页,直到点到某页后没数据
|
44
ty89 2018-04-02 13:57:36 +08:00
不好说,这个得看业务情况具体分析,不过多数情况下用假分页就行了,比如微博的 timeline,不可能给你算 total 的
|
45
hadixlin 2018-04-02 14:11:37 +08:00 via iPhone
楼主的基础知识薄弱呀,这个 count 的问题可能是很复杂的优化,考虑成本来说,一般都是不做的
|
46
logOo 2018-04-02 14:18:34 +08:00
@wangbenjun5 嗯,你这个思路很好。
|
47
jadec0der 2018-04-02 14:21:02 +08:00
笑~很多时候前端开发表现的像普通用户一样。
不知道你是多大的数据量,数据量大了以后 total 确实很难取,很多场景都是估算或者只给前面一部分结果,比如 Google 搜索,result 数量是估算的,翻页一般也只能翻几十页 |
48
panlilu 2018-04-02 14:22:49 +08:00
数据量大的情况查 total 是挺难的……
|
49
3a3Mp112 2018-04-02 14:24:13 +08:00
根本没说清楚这个 total 指的是什么数据,是每次请求回来的有效数量,还是什么?
|
50
w0000 2018-04-02 14:28:08 +08:00
数据大,有 where 条件,条件多并且组合也多的时候,是快不了的啊楼主
|
51
Immortal 2018-04-02 14:28:13 +08:00
其实看完描述我有几个问题和想法
1、从别的地方取是哪里取?如果他这个接口里不好传,别的地方就能传了? 2、这个应该不是全表扫,会走主键索引应该,都不会回表才是 结果和楼上们说的一样,得看数据量才能决定,不是百万千万的 count 还是很快的,如果有连续主键都不用 count,取最大自增主键就好。以前我也经常和客户端吵这类问题,因为我发现他们没法理解服务端需要考虑的问题。归根结底还是没好好沟通,两边都有点责任,抽个时间和服务端聊下解决方案好了。具体服务端的优化方式楼上很多了。 |
52
MushishiXian 2018-04-02 14:38:15 +08:00
有时候 count 真的会挺慢的,加缓存你又要考虑各种查询条件,如果这个 total 不是特别重要,就真的没必要去 count
|
53
jydeng 2018-04-02 14:40:26 +08:00
total 确实很复杂,我们现在表数据量小的话,一般查询两次,一次查 total,一次分页查具体数据。
|
54
iyaozhen 2018-04-02 14:47:32 +08:00 via Android
抛开数据量和场景都是耍流氓
|
55
vincenttone 2018-04-02 14:55:29 +08:00
- 如果数据量大做了分表,恐怕后端就需要做个计数器(还不一定保证准确)。
- 如果数据量小不做分表,多一次 IO。可以不扫全表,前提是有可用的索引。 |
56
sm0king 2018-04-02 15:04:00 +08:00
不管什么原因,该一个请求返回过来的数据,非要请求两条,还有,丢过来一堆数据让前端自己做数据处理对接的后台,都是偷懒。
|
57
play78 2018-04-02 15:07:51 +08:00
这个还是要根据实际业务来, 如果是必须的,那就提供呗。客户能接收等待时间,就多等几秒。
如果业务中,不是必须的,就不用了。 例如,查询记录类的数据。只要告诉用户有下一页就可以。不用提供总共有多少页。让用户一直下一页,下一页。 又比如,一些动态排名之类的。可以后端起个定时任务,每 10 分钟更新一次数据。 如果是要求实时类的,比如一些余额。那就必须要每次都统计了。 |
58
JamesPan 2018-04-02 15:18:25 +08:00
@kera0a myisam count 很快,innodb count 真的是扫全表,可以用 explain 得到的影响行来大致顶替 count
|
59
glues 2018-04-02 15:22:22 +08:00
ls 的某些高手很多啊,吹牛不要钱是吗?
|
60
Sunshow 2018-04-02 15:52:14 +08:00
是很难,没必要最好别用
|
61
weizhen199 2018-04-02 15:53:48 +08:00
有个办法,去统计信息里拿总行数,大致是精准的
|
62
toono 2018-04-02 16:06:03 +08:00
内心 OS: 他到底在说 MySQL 还是 MongoDB.....
|
64
tairan2006 2018-04-02 16:12:38 +08:00
真太大了就用 es/solr 查…
|
65
RTNelo 2018-04-02 16:17:59 +08:00
还好在我司没遇到过大表显示页号的需求,给前端传个 `is_end` 就行了
|
66
Immortal 2018-04-02 16:19:15 +08:00
@weizhen199
这个的确可以,innodb 的查询优化器里应该有个大概数据用来做优化推算 |
67
chenqh 2018-04-02 16:27:17 +08:00
@weizhen199 不会拿。。
|
68
barbery 2018-04-02 16:37:58 +08:00
很烦这种分页,最完美的分页就是游标(逃
|
69
cysroad 2018-04-02 16:38:00 +08:00
如果一个表几百万的数据,一页 20 条,你显示个总页数有意思吗?分页带 total,一般只做 50 页以内的
|
70
kimmykuang 2018-04-02 16:38:08 +08:00
这个不是量大了都会遇到的问题么,简单就是做异构索引上 es,mysql innodb 千万各种条件 count,给个完美的方案?
|
71
icegreen 2018-04-02 16:51:48 +08:00
应该传 / 后端不行
|
72
icegreen 2018-04-02 16:55:53 +08:00
这种肯定是从用户 /产品设计的角度去出发, 第一要考虑的肯定是用户的体验和满足产品的需求;
另外接口设计肯定是要为使用者服务和考虑的, 至少我们是这样要求的. |
73
JKeita 2018-04-02 17:05:41 +08:00
不管你建不建索引,只要命中的数据量很大时,查 total 本来就很慢
|
75
RubyJack 2018-04-02 17:09:54 +08:00
你看看淘宝网给不给你翻到最后一页?
count 就是性能杀手,能不做就不做,后端没毛病。 |
76
wengjin456123 2018-04-02 17:11:57 +08:00
楼主没毛病啊,total 当然要给啊
|
77
nxtxiaolong 2018-04-02 17:12:11 +08:00
这个看数据库本身表中有没有存这个字段了,比如 mongodb 就每隔 collection 有这样的字段,没啥大问题,如果涉及到全表扫面,建立索引也是很慢的~
|
78
JKeita 2018-04-02 17:12:12 +08:00
数据量大就用 ES,才比较好解决
|
79
JKeita 2018-04-02 17:15:03 +08:00
还有即使是 ES 也会限制页数,页数越大查询越慢。所以数据量很大时,传 total 根本就毫无意义
|
80
maemual 2018-04-02 17:21:54 +08:00
如上面所说,我们不知道你们的业务场景到底是什么,上面动不动随便让人用 ES 的也都是随便瞎说。只能说的是,在某些场景下,取 count 可能确实是一个很麻烦的事情。所以希望能够对后端更加宽容,去了解为什么之后,好好的沟通。
|
81
jason19659 2018-04-02 17:30:07 +08:00
所以百万级的数据展示准确的 total 有什么意义。。数据少直接 count
|
82
dishuibaby 2018-04-02 17:47:15 +08:00
我们数据量比较大的时候。就用 solr 查询了。
还有就是给前端用户的展现。通常展现的都固定条件的列表,也不需要展现所有的数据列表吧。应该也不会有很复杂的搜索让用户自己选择。如果查询条件真的复杂了,那就要借助其他工具了。solr es xunsearch 都可以把 如果只是用 mysql 查,我们通常做的是最多展现 1000 页。 |
83
aliasliyu4 2018-04-02 18:01:43 +08:00 via iPhone
数据量很大的时候,我真的做不到啊,您继续喷吧,或者您来?
|
84
chairuosen 2018-04-02 18:19:11 +08:00
海量数据不是给人看的,给人看的拿 100 页足够
|
85
LichMscy 2018-04-02 18:25:34 +08:00
哈哈看标题第一反应没建索引,点进来果然
|
86
adablue77 2018-04-02 18:48:28 +08:00
如果你是前端 要明白自己职责是展现数据
数据都不给你 展现个毛线啊 性能优化不是你需要考虑的范围 产品原型确实需要 total 值 就跟写接口的要去 如果真是百万千万级的分页 你们后端会找产品撕逼的 不用你管 以性能推脱 不给数据 那直接出静态页多好 保证快 |
87
jjx 2018-04-02 19:00:23 +08:00
搞 erp 的哭了
每次报表必须有小计合计, 怎么也逃不过查询理论上执行了两次的命运 |
89
yiplee 2018-04-02 19:23:46 +08:00
展示总评论总数查询条件不复杂性能肯定没问题
|
90
liuxu 2018-04-02 19:36:22 +08:00
需要建汇总表,《高性能 mysql 》一书建议可以用 Flexviews 插件
|
91
projectzoo 2018-04-02 19:38:37 +08:00
这个 count 确实不是简单的 count。。。
一个 comment 表中查询某一条 news 的 comment count 真的不是简单得 select count(*) 这么搞。 |
92
jyf 2018-04-03 10:04:24 +08:00
count 确实慢 不过不给是不对的 我就是做后端的 后端不应该把自己的技术困难推给调用方 如果真的很慢 那就上缓存 告知不能达到很高实时性就可以了
|
93
petelin 2018-04-03 10:31:30 +08:00
700 万 700MB, 花了 1.59 秒
6000 万 2.3G, count 不出来(已经没耐心等待返回了) |
94
winglight2016 2018-04-10 19:17:12 +08:00
@EmdeBoas 那我是没机会用了,小厂完全用不上
|