MySQL使用load data local infile 从文件中导入数据比insert语句要快,MySQL文档上说要快20倍左右。
但是这个方法有个缺点,就是导入数据之前,必须要有文件,也就是说从文件中导入。这样就需要去写文件,
以及文件删除等维护。某些情况下,比如数据源并发的话,还会出现写文件并发问题,很难处理。
那么有没有什么办法,可以达到同样的效率,直接从内存(IO流中)中导入数据,而不需要写文件呢?
前段时间,去MySQL社区的时候发现了这样一个方法:setLocalInfileInputStream(),此方法位于com.mysql.jdbc.PreparedStatement 类中

通过使用 MySQL JDBC 的setLocalInfileInputStream 方法实现从Java InputStream中load data local infile 到MySQL数据库中。

 use test;
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`a` int(11) NOT NULL,
`b` bigint(20) unsigned NOT NULL,
`c` bigint(20) unsigned NOT NULL,
`d` int(10) unsigned NOT NULL,
`e` int(10) unsigned NOT NULL,
`f` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `a_b` (`a`,`b`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
     package com.seven.dbTools.DBTools;  

     import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import org.apache.log4j.Logger; /**
* @author seven
* @since 07.03.2013
*/
public class BulkLoadData2MySQL { private static final Logger logger = Logger.getLogger(BulkLoadData2MySQL.class);
private JdbcTemplate jdbcTemplate;
private Connection conn = null; public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
} public static InputStream getTestDataInputStream() {
StringBuilder builder = new StringBuilder();
for (int i = 1; i <= 10; i++) {
for (int j = 0; j <= 10000; j++) { builder.append(4);
builder.append("\t");
builder.append(4 + 1);
builder.append("\t");
builder.append(4 + 2);
builder.append("\t");
builder.append(4 + 3);
builder.append("\t");
builder.append(4 + 4);
builder.append("\t");
builder.append(4 + 5);
builder.append("\n");
}
}
byte[] bytes = builder.toString().getBytes();
InputStream is = new ByteArrayInputStream(bytes);
return is;
} /**
*
* load bulk data from InputStream to MySQL
*/
public int bulkLoadFromInputStream(String loadDataSql,
InputStream dataStream) throws SQLException {
if(dataStream==null){
logger.info("InputStream is null ,No data is imported");
return 0;
}
conn = jdbcTemplate.getDataSource().getConnection();
PreparedStatement statement = conn.prepareStatement(loadDataSql); int result = 0; if (statement.isWrapperFor(com.mysql.jdbc.Statement.class)) { com.mysql.jdbc.PreparedStatement mysqlStatement = statement
.unwrap(com.mysql.jdbc.PreparedStatement.class); mysqlStatement.setLocalInfileInputStream(dataStream);
result = mysqlStatement.executeUpdate();
}
return result;
} public static void main(String[] args) {
String testSql = "LOAD DATA LOCAL INFILE 'sql.csv' IGNORE INTO TABLE test.test (a,b,c,d,e,f)";
InputStream dataStream = getTestDataInputStream();
BulkLoadData2MySQL dao = new BulkLoadData2MySQL();
try {
long beginTime=System.currentTimeMillis();
int rows=dao.bulkLoadFromInputStream(testSql, dataStream);
long endTime=System.currentTimeMillis();
logger.info("importing "+rows+" rows data into mysql and cost "+(endTime-beginTime)+" ms!");
} catch (SQLException e) {
e.printStackTrace();
}
System.exit(1);
} }

提示:
String testSql ="LOAD DATA LOCAL INFILE 'sql.csv' IGNORE INTO TABLE test.test (a,b,c,d,e,f)";

使用setLocalInfileInputStream方法,会直接忽略掉文件名称,而直接将IO流导入到数据库中。

参考:
http://assets.en.oreilly.com/1/event/21/Connector_J%20Performance%20Gems%20Presentation.pdf

Java不写文件,LOAD DATA LOCAL INFILE大批量导入数据到MySQL的实现(转)的更多相关文章

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

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

  2. load data local infile

    发财 基本语法:load data [low_priority] [local] infile '文件名称' [replace替换策略 | ignore忽略策略]into table 表名称[fiel ...

  3. [MySQL]load data local infile向MySQL数据库中导入数据时,无法导入和字段不分离问题。

    利用load data将文件中的数据导入数据库表中的时候,遇到了两个问题. 首先是load data命令无法执行的问题: 命令行下输入load data local infile "path ...

  4. MySQL使用LOAD DATA LOCAL INFILE报错

    在windows系统的MySQL8.0中尝试执行以下语句时报错 mysql> LOAD DATA LOCAL INFILE '/path/filename' INTO TABLE tablena ...

  5. 浅谈MySQL load data local infile细节 -- 从源码层面

    相信大伙对mysql的load data local infile并不陌生,今天来巩固一下这里面隐藏的一些细节,对于想自己动手开发一个mysql客户端有哪些点需要注意的呢? 首先,了解一下流程: 3个 ...

  6. MySQL用Load Data local infile 导入部分数据后中文乱码

    今天在两台MySQL服务器之间导数据,因为另一个MySQL服务器是测试用的,差一个月的数据,从现有MySQL服务器select到一个文件,具体语句是: select * from news where ...

  7. Load data local infile 实验报告

    1.实验内容: 利用SQL语句“load data local infile”将“pet.txt”文本文件中的数据导入到mysql中 (pet表在数据库menagerie中) 2.实验过程及结果: ( ...

  8. JDBC使用MYSQL的LOAD DATA LOACAL INFILE和LOAD DATA INFILE

    MYSQL的LOAD方法都必须建立在mysql服务允许使用该命令的情况下: 开启该命令的方法: 1.在实例对应的my.cnf(windows为my.ini)中添加一行local-infile=1(默认 ...

  9. Mybatis拦截器 mysql load data local 内存流处理

    Mybatis 拦截器不做解释了,用过的基本都知道,这里用load data local主要是应对大批量数据的处理,提高性能,也支持事务回滚,且不影响其他的DML操作,当然这个操作不要涉及到当前所lo ...

随机推荐

  1. redis 与 序列化

    概念 序列化:把对象转化为可传输的字节序列过程称为序列化. 反序列化:把字节序列还原为对象的过程称为反序列化. 为什么需要序列化 序列化最终的目的是为了对象可以跨平台存储,和进行网络传输.而我们进行跨 ...

  2. PHP流程控制之嵌套if...else...elseif结构

    还记得本章开篇我们讲了一个王思总同学的例子: 王同学是生活极度充满娱乐化和享受生活的人.他抵达北京或者大连的时候做的事,他抵达后做的事情,如下:直线电机参数 半夜到达,先去夜店参加假面舞会 早上抵达, ...

  3. Laravel $request 常用方法

    request的方法 描述 input('key','default-value') 此方法可以获取get请求所带来的特定参数的值,如果没有该参数可以提供默认值 all() 此方法获取get请求的所有 ...

  4. learning scala How To Create Variable Argument Function - varargs :_ *

    Scala collection such as List or Sequence or even an Array to variable argument function using the s ...

  5. cf242 E

    题意: $n$ 个数 $a_i$, 两种询问 $1, l, r$ 查询 $[l, r]$ 的和 $2, l, r, x$ 将区间 $[l, r]$ 所有数异或 $x$ 建立 $30$ 课线段树 第 $ ...

  6. uoj #139

    树链剖分//模板题由于存在换根操作对所有关于节点 u 的修改和查询操作进行分类讨论若 Root 在 u 的子树中,则不处理 u 所在的 Root 的那颗子树否则不会有影响寻找 Root 所在的那颗子树 ...

  7. P4316 绿豆蛙的归宿 期望DP

    P4316 绿豆蛙的归宿 期望DP DAG上,每条边有边权,走向相连每条路的概率相等,问从起点到终点所经过的路径总长度期望 因为发现终点走到终点期望为0,定义\(f[i]\)从终点走到\(i\)所经过 ...

  8. Zotero使用教程(1)-安装及配置

    小书匠kindle   作为一名科研人员,经常要阅读大量文献(当然我收集>>阅读,哎!),收集来的文献一般我们使用文件夹管理,通常使用文件夹命名和层级分布解决论文的分类问题.   但是,实 ...

  9. codeforces396C

    On Changing Tree CodeForces - 396C You are given a rooted tree consisting of n vertices numbered fro ...

  10. 2017杭电ACM集训队单人排位赛 - 2 题解

    1001,水题,直接模拟即可.比赛中开局连wa三发,因为把int写成了bool.. 1002,积分题,比赛中找到了下面这个积分公式, 但是并没什么用,,因为带入以后存在误差,估计是展开了以后出现了误差 ...