这种情况下是否需要分表

2020-05-13 19:03:29 +08:00
 mamasan
很久前一个项目了. 就是类似支付宝年度账单这种.

数据库是 SQL Server. 数据一亿多条吧.

很简单的接口, 传入用户的 id, 返回这条记录.

因为加了索引, 所以查询起来都是 ms 级的, 所以就没做分表了.

但是甲方后来知道了, 就开始责备为什么不分表.

所以想问下, 如果查询时间上完全没有问题, 数据也是一次导入不会增加了. 这种情况下, 不分表有问题吗?

还是说会影响到整个数据库性能?
1620 次点击
所在节点    数据库
17 条回复
littlewing
2020-05-13 19:08:16 +08:00
甲方是爸爸,他们怎么说你怎么来
mamasan
2020-05-13 19:10:47 +08:00
@littlewing 事情已经过了, 纯技术方面探讨. 想知道下, 这种大表是否会造成数据库性能的问题. 特别是也有别的项目在同一个数据库上.
opengps
2020-05-13 19:37:18 +08:00
你可以先轻松用表分区来稍微提高下查询效率
saulshao
2020-05-13 19:47:09 +08:00
你说的情况,目前的数据量一亿,不会再增加,不分表问题不大。
但是这种事情其实很难预料,也许你的争论对立方掌握了什么你不知道的信息也不一定。
chiuan
2020-05-13 19:49:51 +08:00
加索引一般都能满足需求了吧。
sagaxu
2020-05-13 19:56:34 +08:00
你这种情况,分表相当于人工给索引增加一层,能带来什么提升?
peyppicp
2020-05-13 20:02:56 +08:00
@sagaxu 多一个哈希和取模能有啥开销?百万级数据量查询和亿级别查询,就算命中索引耗费的时间远大于哈希取模。

如果耗时 10ms 内可以不用优化。pct99 一直不稳的话可以考虑分库分表
index90
2020-05-13 20:08:34 +08:00
其实甲方想要的是这个系统可扩容,如果你有扩容方案,不分表也行。
你现在是 sql server,你可以用分区啊
sagaxu
2020-05-13 20:18:09 +08:00
sharding 的目的是让数据分布到不同的 instance,一般是不同的 server,多台 server 的 cpu 和 io 能力可以叠加。

同一个 instance 内,有时会分表或分区,比如订单按日期分,由于一般情况只会访问几个月以内的订单,分区做到了冷热数据分离,减少了热数据规模。

但是同一个 instance 内,不区分冷热数据的分表,提升就不太明显了,虽然很多项目都无脑这么做。
starcraft
2020-05-13 20:22:54 +08:00
甲方居然还会管分表管这么细。一亿数据,只要你说的 ms 不是以千计的那种,那真是吃饱了撑的。建议让甲方派个自己的技术来指导,这个人肯定懂的多,批要求一个个的。
sagaxu
2020-05-13 20:27:30 +08:00
@peyppicp hash 之后不还得查索引?把一个大索引拆成 10 个小索引,如果这 10 个没有冷热之分,总量并没有减少。
peyppicp
2020-05-14 11:31:35 +08:00
@sagaxu 大索引命中单条数据硬盘 io 次数不一样吧,一般来讲,按照 mysql 的 b+树, 百万数据 3 次 io,千万数据 4 次 io 了。亿级别的数据 5 次 io

总量没有减少,但是你查询只会落到分片上,不会走所有索引啊。5 次 io 减少到 3 次 io 提升已经很明显了好吧
sagaxu
2020-05-14 15:53:20 +08:00
@peyppicp 从 5 次减少到 3 次,得分几千个表了,定位这几千个表本身也是两层查找,总查找层数似乎没有减少。极端情况下,我每 20 条记录分一个表,是不是就只有一次 IO 了?
peyppicp
2020-05-14 19:54:24 +08:00
@sagaxu 索引键合理的话,千万条以下可以 3 次 io 。
5 次 io 到 3 次 io 要分几千个表,是线上业务中没有走过这块逻辑吧?这种情况下简单分 101 个表就足够了,亿级别数据直接降到百万,不知道你几千个表怎么算出来的。

极端情况不用提了,没啥意义
sagaxu
2020-05-14 20:21:00 +08:00
@peyppicp 按一个节点 50 到 100 个算,两层就是 2500 到 10000 。

1. 分 n 个表之后,每个表索引是之前的 1/n
2. n 个分表的总索引大小,跟分表前一样
3. 随机全量查一次每一行,相当于随机遍历索引的每一个节点
4. IO 总量就是索引读取量
5. 索引量一样,所以 IO 量一样

本来有 5 层的时候,如果第 4 层开始频繁出现 cache miss,分表之后,每个表能用的 cache 也要被平分,可能第 3 层就开始频繁的 cache miss 了,均摊下来磁盘 IO 次数并没有减少。
peyppicp
2020-05-14 20:29:51 +08:00
@sagaxu 楼主这里有明确的 userId,这种情况不需要查全量的索引,这种只要 hash 一下 userId 确定哪个表好了吧,这种时候索引量就是 1/n,io 也少了
如果要全表扫描分库分表的方案很难做罢了,只能借助于 hive
sagaxu
2020-05-14 21:31:49 +08:00
@peyppicp 只查一个用户,只落到一个分区,这是把数据规模缩小到 1/n 了,当然快的多。现实场景不会给你只命中少量表的局部性优势,任意一分钟内都会多次命中所有表。

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

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

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

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

© 2021 V2EX