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

这种情况下是否需要分表

  •  
  •   mamasan · 2020-05-13 19:03:29 +08:00 · 1585 次点击
    这是一个创建于 1648 天前的主题,其中的信息可能已经有所发展或是发生改变。
    很久前一个项目了. 就是类似支付宝年度账单这种.

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

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

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

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

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

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

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

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

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

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

    极端情况不用提了,没啥意义
    sagaxu
        15
    sagaxu  
       2020-05-14 20:21:00 +08:00 via Android
    @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
        16
    peyppicp  
       2020-05-14 20:29:51 +08:00
    @sagaxu 楼主这里有明确的 userId,这种情况不需要查全量的索引,这种只要 hash 一下 userId 确定哪个表好了吧,这种时候索引量就是 1/n,io 也少了
    如果要全表扫描分库分表的方案很难做罢了,只能借助于 hive
    sagaxu
        17
    sagaxu  
       2020-05-14 21:31:49 +08:00 via Android
    @peyppicp 只查一个用户,只落到一个分区,这是把数据规模缩小到 1/n 了,当然快的多。现实场景不会给你只命中少量表的局部性优势,任意一分钟内都会多次命中所有表。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1367 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 17:55 · PVG 01:55 · LAX 09:55 · JFK 12:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.