当你需要在 MySQL 数据库中批量插入数百万条数据时,你就会意识到,逐条发送 INSERT 语句并不是一个可行的方法。

MySQL 文档中有些值得一读的 INSERT 优化技巧。

在这篇文章里,我将概述高效加载数据到 MySQL 数据库的两大技术。

LOAD DATA INFILE

如果你正在寻找提高原始性能的方案,这无疑是你的首选方案。LOAD DATA INFILE 是一个专门为 MySQL 高度优化的语句,它直接将数据从 CSV / TSV 文件插入到表中。

有两种方法可以使用 LOAD DATA INFILE。你可以把数据文件拷贝到服务端数据目录(通常 /var/lib/mysql-files/),并且运行:

LOAD DATA INFILE '/path/to/products.csv' INTO TABLE products;

这个方法相当麻烦,因为你需要访问服务器的文件系统,为数据文件设置合适的权限等。

好消息是,你也能将数据文件存储在客户端,并且使用 LOCAL 关键词:

LOAD DATA LOCAL INFILE '/path/to/products.csv' INTO TABLE products;

在这种情况下,从客户端文件系统中读取文件,将其透明地拷贝到服务端临时目录,然后从该目录导入。总而言之,这几乎与直接从服务器文件系统加载文件一样快,不过,你需要确保服务器启用了此 选项。

LOAD DATA INFILE 有很多可选项,主要与数据文件的结构有关(字段分隔符、附件等)。请浏览 文档 以查看全部内容。

虽然从性能角度考虑, LOAD DATA INFILE 是最佳选项,但是这种方式需要你先将数据以逗号分隔的形式导出到文本文件中。如果你没有这样的文件,你就需要花费额外的资源来创建它们,并且可能会在一定程度上增加应用程序的复杂性。幸运的是,还有一种另外的选择。

扩展的插入语句(Extended inserts)

一个典型的 INSERT SQL 语句是这样的:

INSERT INTO user (id, name) VALUES (1, 'Ben');

extended INSERT 将多条插入记录聚合到一个查询语句中:

INSERT INTO user (id, name) VALUES (1, 'Ben'), (2, 'Bob');

关键在于找到每条语句中要插入的记录的最佳数量。没有一个放之四海而皆准的数字,因此,你需要对数据样本做基准测试,以找到性能收益的最大值,或者在内存使用和性能方面找到最佳折衷。

为了充分利用 extended insert,我们还建议:

  • 使用预处理语句
  • 在事务中运行该语句

基准测试

我要插入 120 万条记录,每条记录由 6 个 混合类型数据组成,平均每条数据约 26 个字节大小。我使用了两种常见的配置进行测试:

  • 客户端和服务端在同一机器上,通过 UNIX 套接字进行通信
  • 客户端和服务端在不同的机器上,通过延迟非常低(小于 0.1 毫秒)的千兆网络进行通信

作为比较的基础,我使用 INSERT ... SELECT 复制了该表,这个操作的性能表现为每秒插入 313,000 条数据

LOAD DATA INFILE

令我吃惊的是,测试结果证明 LOAD DATA INFILE 比拷贝表更快

  • LOAD DATA INFILE:每秒 377,000 次插入
  • LOAD DATA LOCAL INFILE 通过网络:每秒 322,000 次插入

这两个数字的差异似乎与从客户端到服务端传输数据的耗时有直接的关系:数据文件的大小为 53 MB,两个基准测试的时间差了 543 ms,这表示传输速度为 780 mbps,接近千兆速度。

这意味着,很有可能,在完全传输文件之前,MySQL 服务器并没有开始处理该文件:因此,插入的速度与客户端和服务端之间的带宽直接相关,如果它们不在同一台机器上,考虑这一点则非常重要。

Extended inserts

我使用 BulkInserter 来测试插入的速度,BulkInserter 是我编写的 开源库 PHP 类的一部分,每个查询最多插入 10,000 条记录:

正如我们所看到的,随着每条查询插入数的增长,插入速度也会迅速提高。与逐条插入速度相比,我们在本地主机上性能提升了 6 倍,在网络主机上性能提升了 17 倍:

  • 在本地主机上每秒插入数量从 40,000 提升至 247,000
  • 在网络主机上每秒插入数量从 1,2000 提升至 201,000

这两种情况都需要每个查询大约 1,000 个插入来达到最大吞吐量。但是每条查询 40 个插入就足以在本地主机上达到 90% 的吞吐量,这可能是一个很好的折衷。还需要注意的是,达到峰值之后,随着每个查询插入数量的增加,性能实际上是会下降。

extended insert 的优势在网络连接的情况下更加明显,因为连续插入的速度取决于你的网络延迟。

max sequential inserts per second ~= 1000 / ping in milliseconds

客户端和服务端之间的延迟越高,你从 extended insert 中获益越多。

结论

不出所料,LOAD DATA INFILE 是在单个连接上提升性能的首选方案。它要求你准备格式正确的文件,如果你必须先生成这个文件,并/或将其传输到数据库服务器,那么在测试插入速度时一定要把这个过程的时间消耗考虑进去。

另一方面,extended insert 不需要临时的文本文件,并且可以达到相当于 LOAD DATA INFILE 65% 的吞吐量,这是非常合理的插入速度。有意思的是,无论是基于网络还是本地主机,聚集多条插入到单个查询总是能得到更好的性能

如果你决定开始使用 extended insert,一定要先用生产环境的数据样本和一些不同的插入数来测试你的环境,以找出最佳的数值。。

在增加单个查询的插入数的时候要小心,因此它可能需要:

  • 在客户端分配更多的内存
  • 增加 MySQL 服务器的 max_allowed_packet 参数配置。

最后,值得一提的是,根据 Percona 的说法,你可以使用并发连接、分区以及多个缓冲池,以获得更好的性能。更多信息请查看 他们博客的这篇文章。

基准测试运行在装有 Centos 7 和 MySQL 5.7 的裸服务器上,它的主要硬件配置有 Xeon E3 @3.8 GHz 处理器,32 GB RAM 和 NVMe SSD。MySQL 的基准表使用 InnoBD 存储引擎。

基准测试的源代码保存在 gist 上,结果图保存在 plot.ly 上。

  • 原文地址:High-speed inserts with MySQL
  • 原文作者:Benjamin Morel
  • 译文出自:掘金翻译计划
  • 译者:司徒公子
  • 校对者:GJXAIOU、QinRoc

[译] MySQL 最佳实践 —— 高效插入数据相关推荐

  1. mysql 优化配置 大批量数据插入_[译] MySQL 最佳实践 —— 高效插入数据

    当你需要在 MySQL 数据库中批量插入数百万条数据时,你就会意识到,逐条发送 INSERT 语句并不是一个可行的方法. MySQL 文档中有些值得一读的 INSERT 优化技巧. 在这篇文章里,我将 ...

  2. 查看mysql数据插入时间_[译] MySQL 最佳实践 —— 高效插入数据

    Get the dolphin up to speed - Photo by JIMMY ZHANG on Unsplash[1] 当你需要在 MySQL 数据库中批量插入数百万条数据时,你就会意识到 ...

  3. 【译】适合dba和开发者的mysql最佳实践

    [文章作者:孙立 链接:http://www.cnblogs.com/sunli/ 更新时间:2010-09-19] 这是今天开始在南非秘鲁利马开始举行OTN LAD Tour的上,我要进行的一个my ...

  4. Docker 启动 MySQL 最佳实践

    Docker 启动 MySQL 最佳实践 本文主要介绍使用 Docker 启动 MySQL 服务的最佳实践,Docker 镜像来自 docker 官方镜像. 启动一个 MySql 5.7 实例 关于版 ...

  5. mysql longblob 读取_MySQL数据库之Mysql的longblob字段插入数据问题解决

    本文主要向大家介绍了MySQL数据库之Mysql的longblob字段插入数据问题解决 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 在使用mysql的过程中,有个问题就是my ...

  6. MySQL · 最佳实践 · 如何索引JSON字段

    概述 MySQL从5.7.8起开始支持JSON字段,这极大的丰富了MySQL的数据类型.也方便了广大开发人员.但MySQL并没有提供对JSON对象中的字段进行索引的功能,至少没有直接对其字段进行索引的 ...

  7. 经验:在mysql中避免重复插入数据的4种方式

    最常见的方式就是为字段设置主键或唯一索引,当插入重复数据时,抛出错误,程序终止,但这会给后续处理带来麻烦,因此需要对插入语句做特殊处理,尽量避开或忽略异常,下面我简单介绍一下,感兴趣的朋友可以尝试一下 ...

  8. mysql 新增从数据库_从零开始学 MySQL - 创建数据库并插入数据

    目录 1.实验内容 2.实验知识点 3.开发准备 4.实验总结 1.实验内容 本次课程将介绍 MySQL 新建数据库,新建表,插入数据以及基本数据类型的相关知识.本节实验将创建一个名为 mysql_s ...

  9. MySQL(12)--- 插入数据

    MySQL 插入数据 MySQL 表中使用 INSERT INTO SQL语句来插入数据. 你可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 语法 以下 ...

  10. 一部分 数据 迁移_11项最佳实践,每次数据中心迁移都必不可少

    随着企业业务和应用的发展,现有基础架构已经无法保障时,数据中心迁移无法避免,企业可能需要迁移来增加容量或推出新功能和服务. 基础架构要求可能会随时间变化,并且可能会考虑使用托管服务提供商或云服务的选项 ...

最新文章

  1. Microbiome:生态中心张丽梅组-植物发育时期驱动玉米微生物组生态角色的分化...
  2. ASP.NET MVC应用程序展示RDLC报表
  3. Oracle 10g客户端的安装和配置
  4. ubuntu的xfce4的display只有一种分辨率选项
  5. GitLab - Ubuntu18搭建GitLab仓库服务器(转)
  6. 什么是用户账户?-联科教育
  7. 查询数据库 收集 (如某个字段不是中文)
  8. 没有基础怎么学习Web前端?相关学习路线又是什么?
  9. 用中位数代替平均数来衡量民生指标
  10. 16位顶尖对冲基金大佬:畅谈量化投资的下个10年!
  11. matlab操作视频教程,matlab2019视频教程
  12. 软件测试主要流程分享
  13. 软考中级软件设计师学习资料分享
  14. badboy录制过程不能登录, 提示脚本错误详解
  15. 【Android取证篇】一键分析APK利器-APK Messenger
  16. 安卓手机微信怎么恢复聊天记录?方法简单轻松搞定
  17. 共射级放大电路—实现最大输出振幅的方法竟如此简单
  18. python3 实现自动生成入账记录表
  19. 苹果状态栏HTML,iphoneX 适配客户端H5页面的方法教程
  20. java计算机毕业设计公益诊疗系统源程序+mysql+系统+lw文档+远程调试

热门文章

  1. 《人性的弱点全集》- [美]戴尔·卡耐基/著
  2. win7音量图标不见了怎么办捏
  3. \ddd与\xdd保姆级讲解
  4. Periodic Strings
  5. Nodejs教程15:net模块初探
  6. 菜鸟保税仓成全球商家进中国首选 秒级通关领先全球
  7. 群晖 重启 mysql_群晖nas修改MariaDB配置文件
  8. XP下IIS相关问题
  9. windows写注册表文件脚本的编写
  10. 扫码点餐系统可以免费使用了