10亿数据如何快速插入MySQL

图片

最快的速度把10亿条数据导入到数据库,首先需要和面试官明确一下,10亿条数据什么形式存在哪里,每条数据多大,是否有序导入,是否不能重复,数据库是否是MySQL?

有如下约束

  1. 10亿条数据,每条数据 1 Kb

  2. 数据内容是非结构化的用户访问日志,需要解析后写入到数据库

  3. 数据存放在Hdfs 或 S3 分布式文件存储里

  4. 10亿条数据并不是1个大文件,而是被近似切分为100个文件,后缀标记顺序

  5. 要求有序导入,尽量不重复

  6. 数据库是 MySQL

首先考虑10亿数据写到MySQL单表可行吗?

数据库单表能支持10亿吗?

答案是不能,单表推荐的值是2000W以下。这个值怎么计算出来的呢?

MySQL索引数据结构是B+树,全量数据存储在主键索引,也就是聚簇索引的叶子结点上。B+树插入和查询的性能和B+树层数直接相关,2000W以下是3层索引,而2000w以上则可能为四层索引。

Mysql b+索引的叶子节点每页大小16K。当前每条数据正好1K,所以简单理解为每个叶子节点存储16条数据。b+索引每个非叶子节点大小也是16K,但是其只需要存储主键和指向叶子节点的指针,我们假设主键的类型是 BigInt,长度为 8 字节,而指针大小在 InnoDB 中设置为 6 字节,这样一共 14 字节,这样一个非叶子节点可以存储 16 * 1024/14=1170

也就是每个非叶子节点可关联1170个叶子节点,每个叶子节点存储16条数据。由此可得到B+树索引层数和存储数量的表格。2KW 以上 索引层数为 4 层,性能更差。

层数 最大数据量
2 1170 * 16 = 18720
3 1170 * 1170 * 16= 21902400 = 2000w
4 1170 * 1170 * 1170 * 16 = 25625808000 = 256亿

为了便于计算,我们可以设计单表容量在1KW,10亿条数据共100个表。

如何高效的写入数据库

单条写入数据库性能比较差,可以考虑批量写入数据库,批量数值动态可调整。每条1K,默认可先调整为100条批量写入。

批量数据如何保证数据同时写成功?MySQL Innodb存储引擎保证批量写入事务同时成功或失败。

写库时要支持重试,写库失败重试写入,如果重试N次后依然失败,可考虑单条写入100条到数据库,失败数据打印记录,丢弃即可。

此外写入时按照主键id顺序顺序写入可以达到最快的性能,而非主键索引的插入则不一定是顺序的,频繁地索引结构调整会导致插入性能下降。最好不创建非主键索引,或者在表创建完成后再创建索引,以保证最快的插入性能。

是否需要并发写同一个表

不能

  1. 并发写同一个表无法保证数据写入时是有序的。

  2. 提高批量插入的阈值,在一定程度上增加了插入并发度。无需再并发写入单表

MySQL存储引擎的选择

Myisam innodb有更好的插入性能,但失去了事务支持,批量插入时无法保证同时成功或失败,所以当批量插入超时或失败时,如果重试,势必对导致一些重复数据的发生。但是为了保证更快的导入速度,可以把myisam存储引擎列为计划之一。

现阶段我引用一下别人的性能测试结果:MyISAM与InnoDB对比分析

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘世中-迷途小书童

欢迎IT从业者的头脑风暴

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值