由于天热,中午吃完饭后不再去逛了,感觉这段时间其实也是可以利用起来的,所以决定每天中午积累一些小的知识点。今天中午,先总结一下最近造数据用到手命令,load data。

使用这个命令的起源是因为最近要做压力测试,需要造数据,当时计划是向一张表中添加200W条数据,试了好几种方式,都感觉太慢,导致本来一件小事折腾了好几天,最终改用load data,基本上轻松搞定。所以在insert大量数据的时候,这个是比较好的选择。

先总结一下在使用load data之前,试用过的几种低效率的方式:

1)由于项目中有我要填充的数据表的DAO,所以我为了省事,直接写了个简单的入库的测试用例,循环调用那个DAO的insert方法,然而我发现非常慢,一万条数据都执行了半个小时,那么相当于2W条就需要一个小时,200W数据就需要200小时,肯定受不了。

2)然后我想到在程序中操作还有些程序启动,连接及释放的过程比较费时间,那就不在程序中做了,直接在mysql客户端做啊,然后我又想了第二个办法,先用程序生成1W条insert语句到一个sql文件中,然后在客户端中用source命令来执行,但是从结果上来看,还是很慢。

最后经同事提醒和之前的经验,决定使用load data 试试,最终在折腾了一些时间之后用起来了,看效果还是相当不错,100W条只花费了我不到2分钟的时间,采用这个方法,几个表的很快就造完了。下面正式介绍一下mysql的load data命令。

一,命令介绍

很多人估计和我一样,希望能百度到一个最全的介绍这个命令的博文,其实对于这个命令的最全介绍,mysql的官方文档上就用,如下:

每次看这样带各种括号的命令就让人头大,但我们可以简化一下,只保留那些最必要的命令符,则以上命令可以简化如下:

load data infile 'file_name' into table tbl_name

看上去简单多了,就四个关键字,简直跟一般的命令一样,那么这个命令是什么意思呢,就是把名为file_name的文件中的数据加载到名为tbl_name的表格中去。看起来非常的好理解。

二、参数详解

知道了命令的意思,我们接下来再看一下上图中各个可选参数的意思

1)LOW_PRIORITY | CONCURRENT: 这个指定了load data操作与其操作表的线程的优化级关系,根据文档说明,这个只对那些只采用了表级别锁(如MYISAM)的引擎有影响,比如InnoDB使用的是行锁,不受这个影响,具体的来说,使用了LOW_PRIORITY,则本操作会在其它线程完成之后再操作,而CONCURRENT会和其它线程同时进行,这个对性能是有一些影响。

2)LOCAL: 这是个非常重要的关键字,指明了文件的位置,简单的说,如果指定了local,则表示文件位于客户端,如果没有,则表示文件在Server端。同时,这个关键字的使用还会影响到load data命令对于错误数据的处理方式。这两者的主要区别如下:

  a) 如果是指定了local,则数据从客户端读取,文档中的说法是会在服务端的临时目录下创建一份文件的copy,但我在测试的时候并没有发现,如果file_name中是绝对路径就不用解释,如果是相对路径,则文件的位置应该是在客户端程序启动的位置,所以为了保险,一般使用绝对路径。由于涉及到数据传输,所以这种方式会相对来说慢一些。

  b)如果未指定local,则文件应该是直接在服务端,这种情况下如果文件名使用的是相对路径,则又分两种情况,一种是文件名前没有相对目录,则直接是在默认数据库的data目录下查找,如果是指定了相对目录,则从server的data目录下寻找。

  c)如果指定了local,则当某条数据处理有误时,系统把这个错误记录为一个warning,不会影响下一条数据的处理,因为涉及到数据传输。而如果没有指定local,则默认情况下,遇到错误后不会继续执行。

  所以,如果我们是在客户端执行load data命令,一定记得加上local参数。

3)REPLACE | IGNORE: 这个指定了如果当前的数据跟表中的数据有惟一性冲突的时候,采用什么样的方式,是替换已有还是忽略当前。特别需要说明的是,当这两种方式都未指定时,如果数据来自于客户端,则重复的数据会忽略,如果来源于服务端,则命令将终止执行。

4)PARTITION: 指定具体的分区,由于之前数据库中没用到过分区,个人对这块也不熟悉,所以暂时不解释,等到了解了再补充。

5)CHARACTER SET : 指定编码集,如果文件的编码跟数据库的编码不一致,可能会出现乱码的问题。所以要注意的是,这里指定的是文件的编码集,而不是数据库的。

6)[{FIELDS | COLUMNS}  [TERMINATED BY 'string']  [[OPTIONALLY] ENCLOSED BY 'char']  [ESCAPED BY 'char'] ]

  这个指定了对于字段的处理方式,FIELDS和COLUMNS应该是用其一即可。TERMINATED表示字段间的分隔符,ENCLOSED BY的意思是字段值由什么符号包围,而ESCAPED表示指定转义字符。

  在不指定这个参数的情况下,默认的字段分隔符是\t, 默认字段值无任何值包围,默认转义字符为\\.(反斜线)

7)  [LINES [STARTING BY 'string']  [TERMINATED BY 'string']]: 

指定每一行的起始符与终止符,默认情况下,起始符为空,终止符为'\n',对于windows产生的文本文件来说,需要指定换行符为'\r\n'.

8)IGNORE number LINES: 忽略文件中的前 number 行,通常情况下,我们生成的文件可能有列名,那么要忽略的放在,这儿的值设置为1即可。需要注意的是这里是行的数量,而不是行号。

9)[(col_name_or_user_var,...)] : 有的时候我们不需要给所有的字段都填充值,这个时候就可以指定列名,以()将列名括起来,注意这里也可以是用户自定义的用户表达式。

10)  [SET col_name = expr,...]: 如果在前一步中指定了用户表达式,那么相应就可以使用列名等于用户表达式的方式来指定,这个我没有用过,给出一个官方的示例如下:

 LOAD DATA INFILE 'file.txt' INTO TABLE t1(column1, @var1) SET column2 = @var1/100;

三、总结:

 经过自己的实际使用之后,个人觉得这个工具在导入大批量数据时还是比较实用的,虽然可选的参数过多,但是正是由于这些可选的参数,使得我们在导入数据时,可以进行很多方面的定制化。


批量导数据之利器-load data[2016-07-11]的更多相关文章

  1. 2016/07/11 PHP接口的介绍与实现

        接口定义了实现某种服务的一般规范,声明了所需的函数和常量,但不指定如何实现.之所以不给出实现的细节,是因为不同的实体可能需要用不同的方式来实现公共的方法定义.关键是要建立必须实现的一组一般原则 ...

  2. SQL基本语句(3) LOAD DATA INFILE

    使用LOAD语句批量录入数据 语法: LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE | IGNOR ...

  3. 使用 LOAD DATA LOCAL INFILE,sysbench 导数速度提升30%

    1. LOAD DATA INFILE 为什么比 INSERT 快? 2. sysbench 压测 MySQL 的四个标准步骤. 3. 怎么让 sysbench 支持 LOAD DATA LOCAL ...

  4. MySQL通过 LOAD DATA INFILE 批量导入数据

    LOAD DATA INFILE 语句用法 参考手册 本文语句参数使用默认值 PHP:  TP框架环境 // 定义文件路径$file_path = 'LOAD_DATA_LOCAL_INFILE.tx ...

  5. MySQL LOAD DATA INFILE—批量从文件(csv、txt)导入数据

    最近做的项目,有个需求(从Elastic Search取数据,业务运算后),每次要向MySQL插入1300万数据左右.最初用MySQL的executemany()一次插入10000条数据,统计的时间如 ...

  6. MySQL中load data infile将文件中的数据批量导入数据库

    有时候我们需要将文件中的数据直接导入到数据库中,那么我们就可以使用load data infile,下面具体介绍使用方法. dao中的方法 @Autowired private JdbcTemplat ...

  7. Mysql 命令 load data infile 权限问题

    [1]Mysql命令load data infile 执行权限问题 工作中,经常会遇到往线上环境mysql数据库批量导入源数据的场景. 针对这个场景问题,mysql有一个很高效的命令:load dat ...

  8. [官方软件] Easy Sysprep v4.3.29.602 【系统封装部署利器】(2016.01.22)--skyfree大神

    [官方软件] Easy Sysprep v4.3.29.602 [系统封装部署利器](2016.01.22) Skyfree 发表于 2016-1-22 13:55:55 https://www.it ...

  9. load data ERROR 1197 (HY000)错误

    有一份csv格式的文件,大小在14G左右.max_binlog_cache_size=4G. 登录mysql实例,选择对应的表通过load data往指定表里导数.大概20分钟左右,报以下错误: ER ...

随机推荐

  1. Entity Framework: Joining in memory data with DbSet

    转载自:https://ilmatte.wordpress.com/2013/01/06/entity-framework-joining-in-memory-data-with-dbset/ The ...

  2. Java开发者值得关注的7款新工具

    云计算.大数据地快速发展催生了不少热门的应用及工具.作为老牌语言Java,其生态圈也出来了一些有关云服务.监控.文档分享方面的工具.本文总结了7款较新的Java工具,大家不妨看下. 1. JClari ...

  3. 通过微信查找SAP TCODE代码

    输入T-CODE查询作用: (包含了16000+ 个SAP T-CODE),扫码关注后可以体验效果 再也不用去记那么多T-CODE用途了 还不试试看 输入关键词:"利润中心" &q ...

  4. T-SQL 公用表表达式(CTE)

    公用表表达式(CTE) 在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式( ...

  5. SQL语句 - 数据操作

    表中数据的变化牵一发而动全身,会同时导致到索引中数据的变化.因此如果查询语句不需要索引,就应该删除无用的索引以提高效率. 一.INSERT语句 1.基本插入语句 insert用于向表中输入数据,其具体 ...

  6. 有了malloc/free为什么还要new/delete ?

    malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存. 对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的 ...

  7. uniGUI试用笔记(十四)TUniTreeView的CheckBox

    TUniTreeView目前版本没有封装CheckBox功能,所以需要手工处理,幸好0.99版提供部分代码了,修改过程如下: 1.uniGUIAbstractClasses.pas单元中修改基类TUn ...

  8. POJ 2887 Big String(块状链表)

    题目大意 给一个字符串,长度不超过 106,有两种操作: 1. 在第 i 个字符的前面添加一个字符 ch 2. 查询第 k 个位置是什么字符 操作的总数不超过 2000 做法分析 好多不同的做法都可以 ...

  9. mysql中替换字符串(正则) 模糊

    例如: abcd(efg)hijk 替换之后是abcdhijk , name)),''); 执行之后,报错:Truncated incorrect DOUBLE value解决办法,经过查询发现是co ...

  10. symfony安装使用

    symfony是一个强大的具有DI特性的框架,目前比较流行的php开发框架Drupal,Laravel底层都是使用了symfony. 想了解symfony更多内容,传送门 安装symfony很简单,一 ...