深聊MySQL,从入门到入坟之:如何优化数据导入?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 深聊MySQL,从入门到入坟之:如何优化数据导入?

1、一次插入多行数据


插入行所需的时间是由以下因素决定的:


・连接:30%

・向服务器发送查询:20%

・解析查询:20%

・插入行:10% x 行的大小

・插入索引:10% x 索引数

・结束:10%


这是引用 参考MySQL 5.7参考手册


可以发现,大部分时间是消耗在客户端与服务器之间的通信,

所以,我们就可以使用insert包含多个值来减少客户端和服务器之间的通信。


为了能更直观的看到效果,

我们还是老规矩,

上例子,在例子中看效果。


1.1 准备测试表及数据

创建测试表及写入数据。


/* 使用ClassDJ这个database */
use ClassDJ;   
 /* 如果表d1存在则删除表t1 */
drop table if exists d1;
 /* 创建表d1 */
 CREAT TABLE ‘d1’ (
'id' int(11) NOT NULL AUTO_INCREMENT,
  'a' varchar(20) DEFAULT NULL ,
  'b' int(20) DEFAULT NULL ,
  'c' datetime NOT NULL  DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`id`)
)ENGINE=InnoDB CHARSET=utf8mb4 ;
/* 如果存在存储过程insert_d1,则删除 */
drop procedure if exists insert_d1;
delimiter;;
/* 创建存储过程insert_d1 */
create procedure insert_d1()
begin
   /* 声明变量i */
  declare i int;
  /* 设置i的初始值为1 */
  set i = 1;
   /* 对满足i<=1000的值进行while循环 */
  while(i<=1000) do
    /* 写入表d1中a、b两个字段,值都为i当前的值 */
    insert into d1(a.b) vlaue(i,i);   
    set i=i+1;
  end while;
end;;
delimiter;
 /* 运行存储过程insert_d1 */
call insert_d1() ;

创建数据的例子,小鱼在《从入门到入坟,深度理解MySQL之:如何让order by、group by查询速度飞起来》有写过。

没看到的,或者好奇的大佬们,可以去瞅一瞅,瞧一瞧。


1.2 导出一条 SQL 包含多行数据的数据文件

为了获取批量导入数据的 SQL,首先对测试表的数据进行备份,备份的 SQL 为一条 SQL 包含多行数据的形式。


命令执行


mysqldump -ucarl_dj -p'123456' -h127.0.0.1 --set-gtid-purged=off --single-transaction --skip-add-locks  ClassDJ d1 >d1.sql

参数解析


image.png

查看d1.sql文件内容


......
DROP TABLE IF EXISTS `d1`;  
/* 按照上面的备份语句备份的数据文件包含drop命令时,需要特别小心,在后续使用备份文件做导入操作时,应该确定所有表名,防止drop掉业务正在使用的表 */
......
CREATE TABLE `d1`......
......
INSERT INTO `d1` VALUES (1,'1',1,'2020-11-04 03:44:10'),(2,'2',2,'2020-11-04  03:44:10'),(3,'3',3,'2020-11-04  03:44:10')......
......

1.3 导出一条SQL只包含一行数据的数据文件

命令执行


mysqldump -ucarl_dj -p'123456' -h127.0.0.1 --set-gtid-purged=off --single-transaction --skip-add-locks --skip-extended-insert ClassDJ d1 >d1_row.sql

参数解析


image.png

查看d1_row.sql文件内容


......
INSERT INTO `d1` VALUES (1,'1',1,'2020-11-04 03:44:10');
INSERT INTO `d1` VALUES (2,'2',2,'2020-11-04 03:44:10');
INSERT INTO `d1` VALUES (3,'3',3,'2020-11-04 03:44:10');
......

1.4 导入时间的对比

一、先导入一条SQL包含多条数据的的数据文件:


命令执行


time mysql -ucarl_dj -p'123456' -h127.0.0.1 ClassDJ <d1.sql

结果显示

real  0m0.214s
user  0m0.010s
sys  0m0.007s

可以看到,耗时时间是 0.214秒


二、我们再来导入一个SQL只包含一条数据的数据文件:


命令执行


time mysql -ucarl_dj -p'123456' -h127.0.0.1 ClassDJ <d1_row.sql

结果显示

real  0m32.315s
user  0m0.066s
sys  0m0.192s

可以看到, 执行时间是 32.315秒


1.5 结论

一次插入多行花费时间0.214秒左右,

一次插入一行花费了32.315秒,

这样一对比,你的选择,是不是就非常的明确了呢~~

Nice

所以,


如果大批量导入时,记得使用一条insert语句插入多行数据的方式。


2 、关闭自动提交


2.1 对比开启和关闭自动提交的效率

Autocommit 开启时会为每个插入执行提交。可以在InnoDB导入数据时,关闭自动提交。


命令执行


SET autocommit=0;
INSERT INTO `d1` VALUES (1,'1',1,'2020-11-04 03:44:10');
INSERT INTO `d1` VALUES (2,'2',2,'2020-11-04 03:44:10');
INSERT INTO `d1` VALUES (3,'3',3,'2020-11-04 03:44:10');
......
COMMIT;

这里可以看到,

我们使用的是 d1_row.sql这个文件的内容;

在前后分别追加了两行参数:


前面追加内容:


SET autocommit=0;


最后追加的内容:


COMMIT;


然后呢,

我们再重新导入这个数据文件,看看效率有没有提升。


命令执行


time mysql -ucarl_dj -p'123456' -h127.0.0.1 ClassDJ <d1_row.sql

显示结果


real   0m2.360s
user  0m0.059s
sys     0m0.208s

嗯,看到没,

在没有关闭自动提交, 时间是 32.315秒;

关闭自动提交后,时间是 2.360秒;


所以:


大批量导入时,关闭自动提交,让多条 insert 一次提交,也可以大大提升导入速度。


3、 总结


所以,提升数据导入速率,可以:

・一次插入的多行值;

・关闭自动提交,多次插入数据的 SQL 一次提交。


总之,找到自己最适合的方法,就是好的 方法。


MySql的学习历程很不简单,所以,要跟得住脚步啊 。

小鱼在重新列举一下,关于MySQL的一些博文。

基本篇:

1.《基本用法总括一》

2.《基本用法总括二》

3.《SQL去重查询数据》

4.《SQL语句多个表查询,inner join的用法》

5.《sql数据库中的 delete 与drop的区别》

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
10天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
93 9
|
1月前
|
SQL 关系型数据库 MySQL
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
MySQL慢查询优化、索引优化,是必知必备,大厂面试高频,本文深入详解,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
|
15天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
56 18
|
14天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
19 7
|
13天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
46 5
|
1月前
|
SQL 关系型数据库 MySQL
MySQL慢查询优化、索引优化、以及表等优化详解
本文详细介绍了MySQL优化方案,包括索引优化、SQL慢查询优化和数据库表优化,帮助提升数据库性能。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
MySQL慢查询优化、索引优化、以及表等优化详解
|
1月前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
36 2
|
1月前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
108 3
|
1月前
|
缓存 关系型数据库 MySQL
如何优化 MySQL 数据库的性能?
【10月更文挑战第28天】
123 1
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
302 1