MySQL如何快速插入数据
前言:
日常学习和工作中,经常会遇到导数据的需求。比如数据迁移、数据恢复、新建从库等,这些操作可能都会涉及大量数据的导入。有时候导入进度慢,电脑风扇狂转真的很让人崩溃,其实有些小技巧是可以让导入更快速的,本篇文章笔者会谈一谈如何快速的导入数据。
注:本篇文章只讨论如何快速导入由逻辑备份产生的SQL脚本,其他文件形式暂不讨论。
1.尽量减小导入文件大小
首先给个建议,导出导入数据尽量使用MySQL自带的命令行工具,不要使用Navicat、workbench等图形化工具。特别是大数据量的时候,用MySQL自带的命令行工具导出和导入比用Navicat等图形化工具要快数倍,而且用Navicat等图形化工具做大数据量的操作时很容易卡死。下面简单介绍下怎么用MySQL自带的命令行工具做导入导出。
# 导出整个实例
mysqldump -uroot -pxxxxxx --all-databases > all_database.sql
# 导出指定库
mysqldump -uroot -pxxxxxx --databases testdb > testdb.sql
# 导出指定表
mysqldump -uroot -pxxxxxx testdb test_tb > test_tb.sql
# 导入指定SQL文件 (指定导入testdb库中)
mysql -uroot -pxxxxxx testdb < testdb.sql
导入的SQL脚本内容大多是先建库建表,然后插入数据,其中耗时最长的应该是insert插入数据了。为了减小文件大小,推荐使用扩展插入方法,即多行一起批量insert,类似这样:insert into table_name values (),(),(),...,(); 。使用扩展插入比一条条插入,文件大小要小很多,插入速度要快好几倍。使用mysqldump导出的文件默认是使用批量插入的方法,导出时可使用--skip-extended-insert 参数改为逐条插入。下面以一张一千万的数据表为例,测试下不同方式导出的文件插入时的速度。
上图可以看出,使用扩展插入的SQL脚本导入大概需要10分钟左右,而一条条插入的SQL脚本导入时间过长,大概1个小时仍然没有导完,一个2个多G的文本导入一个多小时仍未结束,等不及的笔者就手动取消了 不过还是可以看出多条一起insert比一条条插入数据要节省数倍的时间。
2.尝试修改参数加快导入速度
在MySQL中,有一对大名鼎鼎的“双一”参数,即 innodb_flush_log_at_trx_commit
与 sync_binlog
。为了安全性这两个参数默认值为1,为了快速导入脚本,我们可以临时修改下这两个参数,下面简单介绍下这两个参数:
innodb_flush_log_at_trx_commit默认值为1,可设置为0、1、2
如果innodb_flush_log_at_trx_commit设置为0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。
如果innodb_flush_log_at_trx_commit设置为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去.
如果innodb_flush_log_at_trx_commit设置为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。sync_binlog默认值为1,可设置为[0,N)
当sync_binlog =0,像操作系统刷其他文件的机制一样,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。
当sync_binlog =N (N>0) ,MySQL 在每写 N次 二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。
这两个参数可以在线修改,若想快速导入,可以按照下面步骤来操作:
# 1.进入MySQL命令行 临时修改这两个参数
set global innodb_flush_log_at_trx_commit = 2;
set global sync_binlog = 2000;
# 2.执行SQL脚本导入
mysql -uroot -pxxxxxx testdb < testdb.sql
# 3.导入完成 再把参数改回来
set global innodb_flush_log_at_trx_commit = 1;
set global sync_binlog = 1;
还有另外一种场景是你的需求是新建从库,或者是不需要产生binlog,这时候导入SQL脚本时可以设置暂时不记录binlog,可以在脚本开头增加 set sql_log_bin=0;
然后再执行导入,这样速度会进一步加快。如果你的MySQL实例没有开启binlog则不需要再执行该语句了。
总结:
本篇文章主要介绍快速导入数据的方法,可能还有其他方法快速导入数据,比如load data或者写程序多线程插入。本文中介绍的方法只适合手动导入SQL脚本,下面总结下本文中提到的方法。
- 使用MySQL自带的命令行工具进行导出导入。
- 使用扩展插入方法,一个insert对于多个值。
- 临时修改innodb_flush_log_at_trx_commit和sync_binlog参数。
- 关闭binlog或者临时不记录binlog。
其实还有一些其他方案,比如先不创建索引,插入数据后再执行添加索引操作;或者先将表改为MyISAM或MEMORY引擎,导入完成后再改为InnoDB引擎。不过这两种方法实施起来较为麻烦且不知效果如何。以上方法只是笔者依据个人经验总结得出,可能不太全面,欢迎各位补充哦。
MySQL如何快速插入数据的更多相关文章
- mysql数据库中插入数据INSERT INTO SET的优势
往mysql数据库中插入数据.以前常用 INSERT INTO 表名 (列名1,列名2…) VALUES(列值1,列值2); 如果在PHP程序中,就会写成如下示例(往商品库里增加商品) $sql = ...
- Presto向分区表快速插入数据时出现'target directory already exists'的原因
因为项目使用Presto作为ETL使用,需要将关系库中的数据导入到Hive中.目前关系库中的数据每天导入一次,在Hive中以天为间隔创建新的分区.思路是正确的,但是在使用的过程中,发现将少量关系库中的 ...
- mysql:insert插入数据过慢如何解决,设置innodb_flush_log_at_trx_commit为0就能解决
问题: 最近在做性能测试,造数据,发现insert好慢,只有几十条每秒,很奇怪,最后再网上找到了原因. 网文如下: MY SQL insert 速度过慢 最近在用MySQL做存储,测试中发现插入数据太 ...
- mysql使用存储过程插入数据后,参数为中文的为?或乱码
最近了解了一下mysql存储过程,之前版本的mysql不支持存储过程,5.0版本后就可以支持存储过程的使用:恰好笔者下载使用版本为5.6.20: 做了一个给表插入数据的简单存储过程,发现打开表后汉字全 ...
- 向mysql中批量插入数据的性能分析
MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下 CREATE TABLE example (example_id INT NOT NULL,name VARCHAR( 5 ...
- Oracle快速插入数据append
1:用merge into 进行匹配更新和插入,2: 开启并行,提高速度3: 如果可以的话加NOLOGING 不写入日志4:如果数据有规律的话,分批次执行 1.使用marge快速插入; MERGE / ...
- MYSQL 4种插入数据的方式比较
4种插入数据的方式 第一种:insert into insert into是最常用的插入数据的方式,可以单条插入,也可以多条,还可以指定从其他表中select然后插入. 详细可以参考:insert语法 ...
- jmeter连接mysql数据库批量插入数据
前提工作: 1.在jmeter官网下载jmeter包(官网地址:https://jmeter.apache.org/).此外还需下载mysql驱动包,如:mysql-connector-java-5. ...
- 关于PHP连接上MySQL但不能插入数据
出现这种情况,有三种可能 1.SQL语句有问题 insert into table_name(field1,field2...) values(value1,value2...); 先在MySQL中粘 ...
随机推荐
- 【LiteOS】LiteOS消息队列
目录 前言 链接 参考 笔录草稿 基本概念 队列运作机制 队列运作原理 消息队列传输方式 消息队列的阻塞机制 出队阻塞 入队阻塞 任务相关函数 任务开发流程 注意事项 * 实战 前言 链接 LiteO ...
- Starting Tomcat v9.0 Server at localhost' has encountered a problem
•问题描述 在通过 Eclipse 打开 Tomcat 时报错: •解决方案 找到 Tomcat 的安装位置,打开 tomcat\bin 目录,找到 shutdown.bat,手动关闭 tomcat: ...
- PAT (Advanced Level) Practice 1005 Spell It Right (20 分) 凌宸1642
PAT (Advanced Level) Practice 1005 Spell It Right (20 分) 凌宸1642 题目描述: Given a non-negative integer N ...
- 【剑指offer】10:矩形覆盖
题目描述: 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 解题思路: ①方法一 对于这种题没有思路怎么办?可以先从最 ...
- 防火墙双出口环境下私网用户通过NAPT访问Internet
组网图形 组网需求 如图1所示,某企业在网络边界处部署了FW作为安全网关,并分别从运营商ISP1和ISP2处购买了宽带上网服务,实现内部网络接入Internet的需求. 具体需求如下: 研发部门和市场 ...
- day10.闭包函数与装饰器
一.闭包函数 1.闭函数:被封闭起来的函数==>定义在函数内部的函数,特点是只能在函数内调用 2.包函数:该函数引用了一个名字,该名字来自于E这一层 总结:闭包函数指的是定义在函数内部的函数引用 ...
- 使用defineProperty实现自定义setter, 简化前端Angular的重构工作
一.问题场景 Angular的双向绑定给我们开发提供了很大的遍历,将父scope的引用变量作为参数传递给子指令,这样就可以方便的在父作用域内进行业务操作,数据变更会自动传递到子指令.但是如果你基于一个 ...
- 1017. Convert to Base -2
Given a number N, return a string consisting of "0"s and "1"s that represents it ...
- NetCore去注册Eureka
首先先安装nuget组件:Steeltoe.Discovery.ClientCore 然后在ConfigureServices中进行注入 services.AddDiscoveryClient(Con ...
- 1.8.7- HTML值label标签
1.label直接进行包裹input就可以了.