最近看到公司的其中一个数据库用户表每个月都要几百万的新用户数据增加,目前单表已经是两千多万了。所以找了 DBA 讨论,发现以前学的知识,以及网上的一些资料其实说的并不是很正确,比如 mysql 单表不建议超过一千万,我司 DBA 数据规范建议是单表最多不超过五千万。DBA 认为单看数据表的行数来决定分不分表是不正确。结合自己的知识和 DBA 的建议,记录一下需要分表的场景:
1. 表字段多,部分字段不经常用,使用 show index from tablename 查看索引状态
2. 表数据占物理空间大
3. 数据库服务器性能问题,使用 show processlist 查看当前连接状态,是否有慢 sql
4. 业务查询较多,查询慢,使用 explain 查询 sql 是否使用索引
5. 业务受到影响,不满足日常需求
分表方式有水平分表,垂直分表。常用的水平分表都是 RANGE 、一致性 HASH 算法 、取模几种方式。分表之后,业务代码、架构也需要调整,比如引入中间件,否则分页,排序,事务都无法处理。
分享一下我 2020 年开发的一个支付系统 MySQL 按月水平分表的例子,当时每天有 10 万笔订单,单表已经 3000 多万的数据,常用查询字段订单号、订单状态、创建时间、商户id、字段已经有添加索引了,查询性能比较差,一个查询要2-3秒。
以下是技术升级改造处理过程:
1. 原有表名为 orders,批量创建一年的分表,按订单创建时间的月份创建,表名为 orders_202001 orders_202002 以此类推,订单流水表也是类似。
2. 创建订单时按获取创建时间加表名,得到分表名称写入数据,创建时间也作为订单号的前缀,根据订单号查询时也能获取到分表名称
3. 将管理后台涉及查询的接口继续改造,添加限制条件,最多只能查询 2 个月时间内的订单,超出的分多次查询,调研了金融类项目都有查询时间限制,可能也是做了水平分表,避免分表之后需要查询所有数据表,查询性能比没有分表更差,查询订单数据时,我们可以使用 UNION ALL 操作符将不同分表的数据合并在一起。
分表之后的业务价值有两点:
1. 查询性能提升、用户体验更佳。
2. 节省服务器成本,如果没有分表,数据库服务器升级配置也可以满足,但是成本更高了。
项目地址
源码资料!