Mysql --学习:大量数据快速导入导出
声明:此文供学习使用,原文:https://blog.csdn.net/xiaobaismiley/article/details/41015783
【实验背景】
项目中需要对数据库中一张表进行重新设计,主要是之前未分区,考虑到数据量大了以后要设计成分区表,同时要对数据库中其他表做好备份恢复的工作。
【实验环境】
Mysql版本:mysql-5.6.19
操作系统:Ubuntu 12.04
内存:32G
CPU:24核 Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz
数据:单表1.6亿条记录,大小为22GB,非分区表,表中包含一个索引,并且存在int型自增主键
【导出导出工作准备】
(1)导出前关闭日志,避免数据备份过程中频繁记录日志
(2)删除主键,关闭自动增长。在该表中主键其实作用不大,自动增长是需要的(mysql中自动增长的一列一定要为key,所以设置为主键),等待数据转移结束后重新设置回来
(3)删除表中索引。在插入数据时索引的存在会很大程度上影响速度,所以先关闭,转移后重新建立
(4)Mysql系统参数调优,如下:(具体含义后面给出)
innodb_data_file_path = ibdata1:1G:autoextend
innodb_file_per_table = 1
innodb_thread_concurrency = 20
innodb_flush_log_at_trx_commit = 1
innodb_log_file_size = 256M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 50
innodb_lock_wait_timeout = 120
key_buffer_size=400M
innodb_buffer_pool_size=4G
innodb_additional_mem_pool_size=20M
innodb_log_buffer_size=20M
query_cache_size=40M
read_buffer_size=4M
read_rnd_buffer_size=8M
tmp_table_size=16M
max_allowed_packet = 32M
【操作方法及结果】
(1)create table t2 as select * from t1
CREATE TABLE dn_location3
PARTITION BY RANGE (UNIX_TIMESTAMP(UPLOADTIME))
( PARTITION p141109 VALUES LESS THAN (UNIX_TIMESTAMP('2014-11-09 00:00:00')),
PARTITION p141110 VALUES LESS THAN (UNIX_TIMESTAMP('2014-11-10 00:00:00')),
PARTITION p141111 VALUES LESS THAN (UNIX_TIMESTAMP('2014-11-11 00:00:00')),
PARTITION p141112 VALUES LESS THAN (UNIX_TIMESTAMP('2014-11-12 00:00:00'))
)
as select * from dn_location
where uploadtime > '2014-08-04';
create table t2 as select * from dn_location2;
as创建出来的t2表(新表)缺少t1表(源表)的索引信息,只有表结构相同,没有索引。
此方法效率较高,在前面的实验环境下,42min内将一张表内4600W的数据转到一张新的表中,在create新表时我添加了分区的操作,因此新表成功创建为分区表,这样一步到位的既转移了数据又创建了分区表。此方法平均速度:6570W条/h ,至于该方法其他需要注意的地方,暂时没有去了解。
(2)使用MySQL的SELECT INTO OUTFILE 、Load data file
LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中。当用户一前一后地使用SELECT ... INTO OUTFILE 和LOAD DATA INFILE 将数据从一个数据库写到一个文件中,然后再从文件中将它读入数据库中时,两个命令的字段和行处理选项必须匹配。否则,LOAD DATA INFILE 将不能正确地解释文件内容。
假设用户使用SELECT ... INTO OUTFILE 以逗号分隔字段的方式将数据写入到一个文件中:
SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM table2;
为了将由逗号分隔的文件读回时,正确的语句应该是:
LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';
如果用户试图用下面所示的语句读取文件,它将不会工作,因为命令LOAD DATA INFILE 以定位符区分字段值:
LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';
下面是我用来导入导出的命令:
select * into outfile 'ddd.txt' fields terminated by ',' from dn_location;
load data infile 'ddd.txt' into table dn_location2 FIELDS TERMINATED BY ',';
通过该方法导出的数据,是将各字段(只有数据,不导出表结构)数据存在一个文件中,中间以逗号分隔,因为文件中并不包含数据库名或者表名,因此需要在导入导出的时候些明确。该方法在18分钟内导出1.6亿条记录,46min内导入6472W条记录,平均速度:8442W条/h。mysql官方文档也说明了,该方法比一次性插入一条数据性能快20倍。
【额外测试1】在新的表结构中增加主键,并增加某一列自增,查看主键索引对插入效率的影响
【结论】导出效率没有变化,导入效率35min中导入4600W条记录,平均速度:7886W/h,考虑到测试次数很少,不能直接下结论,但至少明确该操作不会有明显的效率下降。
【测试语句】
SELECT MOTOR_ID,LAT,LON,UPLOADTIME,RECEIVETIME,STATE_ID,SYS_STATE_ID,SPEED,DIR,A,GPRS,DISTANCE,WEEKDAY,GPSLOCATE INTO OUTFILE 'import2.txt' FROM dn_location3;
LOAD DATA INFILE 'import2.txt' INTO TABLE dn_location_withkey(MOTOR_ID,LAT,LON,UPLOADTIME,RECEIVETIME,STATE_ID,SYS_STATE_ID,SPEED,DIR,A,GPRS,DISTANCE,WEEKDAY,GPSLOCATE);
【额外测试2】在新建的表中对一个varchar类型字段增加索引,再往里导入数据,查看对插入效率的影响。
【结论】导入4600W条记录耗时47min,效率确实有所降低,比仅有主键索引的测试多了12分钟,从这里看插入效率排序: 没有任何索引 > 主键索引 > 主键索引+其他索引。
【额外测试3】在新建表中不加索引导入数据,完全导入后再建索引,查看建立索引时间
【结论】(1)表数据4600W,建立索引时间10min;表数据1.6亿条,建立索引时间41min,由此可见建立索引的时间与表的数据量有直接关系,其他影响因素比较少;(2)从此处看先插入数据再建索引与先建索引再批量插入数据时间上差距不大,前者稍快一些,开发中应根据实际情况选择。
(3)使用mysqldump ,source
mysqldump -u root -p -q -e -t webgps4 dn_location2 > dn_location2.sql
mysqldump -u root -p -q -e -t --single-transaction webgps4 dn_location2 > dn_location2.sql
source dn_location2.sql
以上是导入导出数据的语句,该方法15分钟导出1.6亿条记录,导出的文件中平均7070条记录拼成一个insert语句,通过source进行批量插入,导入1.6亿条数据耗时将近5小时。平均速度:3200W条/h。后来尝试加上--single-transaction参数,结果影响不大。另外,若在导出时增加-w参数,表示对导出数据进行筛选,那么导入导出的速度基本不变,筛选出的数据量越大,时间越慢而已。对于其中的参数这里进行说明:
–quick,-q
该选项在导出大表时很有用,它强制 mysqldump 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中。
--extended-insert, -e
使用具有多个VALUES列的INSERT语法。这样使导出文件更小,并加速导入时的速度。默认为打开状态,使用--skip-extended-insert取消选项。
--single-transaction
该选项在导出数据之前提交一个BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储引擎,仅InnoDB。本选项和--lock-tables 选项是互斥的,因为LOCK TABLES 会使任何挂起的事务隐含提交。要想导出大表的话,应结合使用--quick 选项。在本例子中没有起到加快速度的作用
mysqldump -uroot -p --host=localhost --all-databases --single-transaction
-t 仅导出表数据,不导出表结构
更多的mysqldump 参数说明请参考:http://blog.chinaunix.net/uid-26805356-id-4138986.html
更多的mysql 参数调优说明参考:http://blog.csdn.net/yang1982_0907/article/details/20123055
http://blog.csdn.net/nightelve/article/details/17393631
extended-insert对mysqldump及导入性能的影响 http://blog.csdn.net/hw_libo/article/details/39583247
参考资料:
http://www.tuicool.com/articles/6jEBJ3 mysql load data infile的使用 和 SELECT into outfile备份数据库数据
http://kevin850115.iteye.com/blog/578142 Load Data使用方法
http://www.jb51.net/article/47525.htm mysql几种导入导出方法介绍
Mysql --学习:大量数据快速导入导出的更多相关文章
- 使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量数据快速导入导出
使用MySQL的SELECT INTO OUTFILE .Load data file LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中.当用户一前一后地使用SELECT ...
- 54.超大数据快速导入MySQL
超大数据快速导入MySQL ----千万级数据只需几十分钟本地测试方法1.首先需要修改本地mysql的编码和路径,找到my.ini.2.在里面添加或修改 character-set-server=u ...
- mysql 数据到 导入导出 总结
数据库数据的导入和导出受secure_file_priv配置项影响#限制导入导出,null时无法进行数据的导入导出,空时不限制,设置了目录则只能对该目录下的文件进行导入导出show variables ...
- 循序渐进开发WinForm项目(5)--Excel数据的导入导出操作
随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...
- SQL Server中bcp命令的用法以及数据批量导入导出
原文:SQL Server中bcp命令的用法以及数据批量导入导出 1.bcp命令参数解析 bcp命令有许多参数,下面给出bcp命令参数的简要解析 用法: bcp {dbtable | query} { ...
- oracle数据的导入导出(两种方法三种方式)
大概了解数据库中数据的导入导出.在oracle中,导入导出数据的方法有两种,一种是使用cmd命令行的形式导入导出数据,另一种是使用PL/SQL工具导入导出数据. 1,使用cmd命令行导入导出数据 1. ...
- Oracle 数据泵导入导出总结
Oracle 数据泵(IMPDP/EXPDP)导入导出总结 Oracle数据泵导入导出是日常工作中常用的基本技术之一,它相对传统的逻辑导入导出要高效,这种特性更适合数据库对象数量巨大的情形,因为我日常 ...
- Oracle 12c pdb的数据泵导入导出
12c推出了可插拔数据库,在一个容器cdb中以多租户的形式同时存在多个数据库pdb.在为pdb做数据泵导入导出时和传统的数据库有少许不同. 1,需要为pdb添加tansnames ...
- MATLAB中文件的读写和数据的导入导出
http://blog.163.com/tawney_daylily/blog/static/13614643620111117853933/ 在编写一个程序时,经常需要从外部读入数据,或者将程序运行 ...
随机推荐
- MySql数据库安装
MySql数据库安装 一丶数据库 什么是数据库 数据库简单连接就是存储数据的容器. 而库则是一组容器合成的东西. 也就是存储数据的.我们编程中常常会用到数据库. 什么是数据管理系统 数据库管理系统就是 ...
- 基于redis的分布式锁实现
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
- 云数据库POLARDB优势解读之①——10分钟了解
什么是POLARDB POLARDB 是阿里云自研的下一代关系型分布式数据库,100%兼容MySQL,之前使用MySQL的应用程序不需要修改一行代码,即可使用POLARDB. POLARDB在运行形态 ...
- shiro源码篇 - 疑问解答与系列总结,你值得拥有
前言 开心一刻 小明的朋友骨折了,小明去他家里看他.他老婆很细心的为他换药,敷药,然后出去买菜.小明满脸羡慕地说:你特么真幸福啊,你老婆对你那么好!朋友哭得稀里哗啦的说:兄弟你别说了,我幸福个锤子,就 ...
- Back-off pulling image \"registry.access.redhat.com/rhel7/pod-infrastructure:latest
Error syncing pod, skipping: failed to "StartContainer" for "POD" with ImagePull ...
- spring-cloud-starter-gateway
********************************************************** Spring MVC found on classpath, which is i ...
- H5调取APP或跳转至下载
来源: 最近在配合移动端做几个详情页h5分享页面,需要调取App并跳转至app详情页, 如果没有安装App,需要判断引导至下载页面. 参考文档: https://juejin.im/post/5b7e ...
- 个渣渣C语言之数组
---恢复内容开始--- 学c语言就知道数组.指针在c中有着特殊的地位.而且是必须掌握的一项知识,学会它会让你受益无穷. 一.数组 1.数组:室友一系列相同元素构成的.它连续的存储在内存中. 2.数组 ...
- 【转载】C#检测客户端输入的内容是否含有危险字符串
用户在客户端提交的内容有时候并不可信,如果客户端提交的内容中含有危险字符串信息,则很有可能造成应用程序安全性问题,如SQL注入风险等.因此在接收客户端提交过来的数据后,我们首先需要判断数据中是否含有危 ...
- DropDownList按照Gridview获取数据获取到的是定义格式
首先需要把DropDownList改成允许服务器返回. 然后绑定的时候需要以下两项. DropDownList1.DataTextField = "name";DropDownLi ...