博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java大批量数据导入(MySQL)
阅读量:4677 次
发布时间:2019-06-09

本文共 6032 字,大约阅读时间需要 20 分钟。

© 版权声明:本文为博主原创文章,转载请注明出处

最近同事碰到大批量数据导入问题,因此也关注了一下。大批量数据导入主要存在两点问题:内存溢出导入速率慢

内存溢出:将文件中的数据全部取出放在集合中,当数据过多时就出现Java内存溢出,此时可通过调大JVM的最大可用内存(Xmx)解决,

        但终究不是王道

        MySQL支持一条SQL语句插入多条记录的操作,并且效率比单条插入快的不是一点点;但是MySQL一次可接受的数据包大小

        也是有限制的,当一次插入过多时也可能造成数据包内存溢出,此时可通过调大MySQL的max_allowed_packet 解决,

        但也不是王道

导入速率慢:单条插入就不用考虑了,因此考虑一条SQL语句插入多条记录,

        根据上述所说还应控制好一条插入的数据大小不能超过max_allowed_packet 的配置。

下面比较了用PreparedStatement和直接拼接SQL两种批量插入的方式的速率(一次插入1w条

 

package org.javaio.CSV;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.InputStreamReader;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.text.SimpleDateFormat;import java.util.Date;import com.mysql.jdbc.Connection;/** * 导入大批量CSV文件 * */public class Test {		/**	 * jdbc所属,暂不使用	 */	private final static String url = "jdbc:mysql://localhost:3306/demo_test?useSSL=true&characterEncoding=utf8";	private final static String name = "root";	private final static String pwd = "20121221";	private static Connection conn;	private static PreparedStatement ps;    	/**	 * 解析csv文件并插入到数据库中,暂不使用(jdbc)	 * 	 * @param args	 * 	 * @throws Exception	 */	public static void main(String[] args) throws Exception {				Test test = new Test();				// psBatch 时间统计 - 开始		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		String startTime = sdf.format(new Date());		System.out.println("psBatch 开始时间为:" + startTime);		System.out.println("psBatch 开始执行...");				// 使用PreparedStatement批量插入		int idx = test.psBatch();				// 统计时间 - 结束		System.out.println("psBatch 执行完成,共插入" + idx + "条数据");		String endTime = sdf.format(new Date());		System.out.println("psBatch 结束时间为:" + endTime);				System.out.println();				// 时间统计 - 开始		startTime = sdf.format(new Date());		System.out.println("sqlBatch 开始时间为:" + startTime);		System.out.println("sqlBatch 开始执行...");				// 使用SQL语句批量插入		idx = test.sqlBatch();				// 统计时间 - 结束		System.out.println("sqlBatch 执行完成,共插入" + idx + "条数据");		endTime = sdf.format(new Date());		System.out.println("sqlBatch 结束时间为:" + endTime);			}		/**	 * 使用PreparedStatement批量插入	 * 	 * @return	 * 	 * @throws Exception	 */	private int psBatch() throws Exception {				int idx = 0;// 行数				try {			// 读取CSV文件			FileInputStream fis = new FileInputStream("C:/Users/chen/Desktop/data/ceshi .csv");			InputStreamReader isr = new InputStreamReader(fis, "UTF-8");			BufferedReader br = new BufferedReader(isr);			String line;// 行数据			String[] column = new String[4];// 列数据						// 获取数据库连接			conn = getConnection();			// 设置不自动提交			conn.setAutoCommit(false);						// SQL			String sql = "insert into test (name, `desc`, column1, column2, column3, column4) "					+ "values (?, ?, ?, ?, ?, ?)";			ps = conn.prepareStatement(sql);						while ((line = br.readLine()) != null) {// 循环读取每一行				idx++;// 计数				column = line.split(",");				ps.setString(1, column[0]);					if (column.length >= 2 && column[1] != null) {					ps.setString(2, column[1]);				} else {					ps.setString(2, "");				}				if (column.length >= 3 && column[2] != null) {					ps.setString(3, column[2]);				} else {					ps.setString(3, "");				}				if (column.length >= 4 && column[3] != null) {					ps.setString(4, column[3]);				} else {					ps.setString(4, "");				}				ps.setString(5, "type");				ps.setString(6, "1");				ps.addBatch();				if (idx % 10000 == 0) {					ps.executeBatch();					conn.commit();					ps.clearBatch();				}			}			if (idx % 10000 != 0) {				ps.executeBatch();				conn.commit();				ps.clearBatch();			}		} catch (Exception e) {			System.out.println("第" + idx + "前一万条数据插入出错...");		} finally {			try {				if (ps != null) {					// 关闭连接					ps.close();				}				if (conn != null) {					conn.close();				}			} catch (Exception e2) {				e2.printStackTrace();			}		}				return idx;			}		/**	 * 使用sql语句批量插入	 * 	 * @return	 * 	 * @throws Exception	 */	private int sqlBatch() {				int idx = 0;// 行数				try {						// 读取CSV文件			FileInputStream fis = new FileInputStream("C:/Users/chen/Desktop/data/ceshi .csv");			InputStreamReader isr = new InputStreamReader(fis, "UTF-8");			BufferedReader br = new BufferedReader(isr);						String line;// 行数据			String[] column = new String[4];// 列数据						// 获取数据库连接			conn = getConnection();						// SQL			StringBuffer sql = new StringBuffer("insert into test (name, `desc`, column1, column2, column3, column4) "					+ "values ");						while ((line = br.readLine()) != null) {// 循环读取每一行				idx++;// 计数				column = line.split(",");				sql.append("('" + column[0] + "', '");				if (column.length >= 2 && column[1] != null) {					sql.append(column[1] + "', '");				} else {					sql.append("', '");				}				if (column.length >= 3 && column[2] != null) {					sql.append(column[2] + "', '");				} else {					sql.append("', '");				}				if (column.length >= 4 && column[3] != null) {					sql.append(column[3] + "', '");				} else {					sql.append("', '");				}				sql.append("type', '1'),");				if (idx % 10000 == 0) {					String executeSql = sql.toString().substring(0, sql.toString().lastIndexOf(","));					ps = conn.prepareStatement(executeSql);					ps.executeUpdate();					sql = new StringBuffer("insert into test (name, `desc`, column1, column2, column3, column4) "							+ "values ");				}			}			if (idx % 10000 != 0) {				String executeSql = sql.toString().substring(0, sql.toString().lastIndexOf(","));				ps = conn.prepareStatement(executeSql);				ps.executeUpdate();			}		} catch (Exception e) {			System.out.println("第" + idx + "前一万条数据插入出错...");		} finally {			try {				if (ps != null) {					// 关闭连接					ps.close();				}				if (conn != null) {					conn.close();				}			} catch (Exception e2) {				e2.printStackTrace();			}		}		return idx;			}		/**	 * 获取数据库连接	 * 	 * @param sql	 * 				SQL语句	 */	private Connection getConnection() throws Exception {				Class.forName("com.mysql.jdbc.Driver");		conn = (Connection) DriverManager.getConnection(url, name, pwd);		return conn;			}	}

 

速率比较:为了排除其他影响,两次次都是在空表的情况下进行导入的

  用SQL拼接批量插入用时大概3-4分钟

 

  用PreparedStatement批量插入用时大概10分钟

 

转载于:https://www.cnblogs.com/jinjiyese153/p/7382345.html

你可能感兴趣的文章
webpack的安装
查看>>
字符流Reader和Writer
查看>>
【校招面试 之 C/C++】第33题 C++ 11新特性(四)之STL容器
查看>>
Java替代C语言的可能性
查看>>
android ListView中CheckBox错位的解决
查看>>
linux下的mongodb数据库原生操作
查看>>
BNUOJ 1268 PIGS
查看>>
菜鸟的MySQL学习笔记(三)
查看>>
商业选址5A法则
查看>>
POJ 1191 棋盘分割(区间DP)题解
查看>>
文件同步服务器,iis 集群 ,代码同步(一)
查看>>
JS之模板技术(aui / artTemplate)
查看>>
【Tomcat】Tomcat Connector的三种运行模式【bio、nio、apr】
查看>>
Mysql-2-数据库基础
查看>>
python把源代码打包成.exe文件
查看>>
再也不用担心网吧开黑队友听不清了!降噪解决方案了解一下?
查看>>
PhotoshopCS5中将单位修改成百分比
查看>>
赵雅智:js知识点汇总
查看>>
变形二叉树中节点的最大距离(树的最长路径)——非递归解法
查看>>
cocos2d-x 3.0rc1 编译cpp-testsproject
查看>>