Java中快速导入数据到mysql
通过Java代码将大约500.000条记录从CSV文件插入MySQL数据库需要多长时间?数据库托管在本地主机上 表结构:Java中快速导入数据到mysql,java,mysql,Java,Mysql,通过Java代码将大约500.000条记录从CSV文件插入MySQL数据库需要多长时间?数据库托管在本地主机上 表结构:AI-id,| varchar(8)| datetime | int | varchar(2)。我的代码需要在40分钟内插入70.000条记录。有什么办法可以更快地完成吗? 以下是我代码的主要部分: CsvReader-pro 管道=新的CsvReader(路径); products.readHeaders(); stmt=con.createStatement(); Stri
AI-id,| varchar(8)| datetime | int | varchar(2)
。我的代码需要在40分钟内插入70.000条记录。有什么办法可以更快地完成吗?
以下是我代码的主要部分:
CsvReader-pro
管道=新的CsvReader(路径);
products.readHeaders();
stmt=con.createStatement();
String updateString=“插入表(T_V1、日期、T_V2、T_V3)值(?、、?、?)”;
PreparedStatement PreparedStatement=con.prepareStatement(updateString);
while(products.readRecord()){
v1=产品。获取(“v1”);
date=format.parse(products.get(“日期”)+“”+products.get(“小时”);
java.sql.dateDB=new java.sql.Date(data.getTime());
v2=产品。获取(“v2”);
v3=products.get(“v3”);
编制报表。设置字符串(1,v1);
编制报表。设置日期(2,日期数据库);
preparedStatement.setInt(3,Integer.parseInt(v2));
编制报表。设置字符串(4,v3);
preparedStatement.executeUpdate();
}
根据你的建议,我将语句的创建移出了循环。现在我每秒有33条记录,在我有29个rps之后。而不是在
while
中创建PreparedStatement
,在while
循环中创建PreparedStatement
并简单地设置值
差不多
String updateString = "INSERT INTO table (T_V1, date, T_V2, T_V3) VALUES (?,?,?,?)";
PreparedStatement preparedStatement = con.prepareStatement(updateString);
while (products.readRecord()) {
v1= products.get("V1");
date = format.parse(products.get("Date") + " " + products.get("Hour"));
java.sql.Date dateDB = new java.sql.Date(data.getTime());
v2 = products.get("V2");
v3 = products.get("V3");
preparedStatement.setString(1, v1);
preparedStatement.setDate(2,dateDB);
preparedStatement.setInt(3, Integer.parseInt(v2));
preparedStatement.setString(4, v3);
preparedStatement.executeUpdate();
}
另外,您应该提交每一行,这些行可以由数据库引擎的内存处理,否则,在插入一定数量后,系统速度会非常快地减慢
请注意,通常应能在40分钟内创建超过70.000条记录。您的网络可能存在瓶颈。它是java应用程序的本地数据库还是远程服务器?如果是远程服务器,请检查连接速度。首先,您可以在循环外创建preparedstatement。您还可以重构代码以使用多线程,因为insert语句似乎互不依赖,所以您可以通过并行拆分来处理所有数据 但是对于你的问题“多久……”没有绝对的答案。
这取决于托管mysql的机器和执行java代码的机器:核心数量、可用内存等。我可能会选择使用
从mysql加载数据
语句,而不是使用java:
LOAD DATA LOCAL INFILE '/path/to/your/file.csv' INTO TABLE table;
假设您在将每一行插入MySQL之前都在处理它,这将避免您当前的大量开销
可以使用原始JDBC从Java执行
LOAD DATA
语句。如果不需要使用Java插入代码,可以使用SQL插入数据
在GUI工具(SQLyog等)中使用以下代码:
你应该选择批量插入
PreparedStatement prepStmt = con.prepareStatement("Insert query");
prepStmt.setString(1,parameter1);
prepStmt.addBatch();
// for next set of parameter
prepStmt.setString(1,parameter2);
prepStmt.addBatch();
int [] numUpdates=prepStmt.executeBatch()
)
看
将语句的创建从while循环中移出您不应该使用Java来导入数据,请使用mysqlimport实用程序。曾经,我不得不基于
pcap
文件将数百万条记录插入数据库。将数据划分成块并使用线程运行它要快得多。不知道它在MySQL中是如何工作的。我使用Oracle DB,让prodcuer线程创建表类型(表示一组DB记录),让使用者线程创建DB事务,并使用这些表类型参数调用存储过程,将数据插入DB。但一般来说,如果已经有CSV文件,最快的方法是使用建议的SQL加载程序替代,只在循环外创建一次“代码> PravaReDebug <代码>,另外,考虑使用批处理插入(<代码> PravaRealStay.AdBATCH()/代码>)。不幸的是,我必须用Java来实现这一点,但是OP明确要求通过Java传递。如果OP关于使用Java来实现这一点的预感是错误的,那么这意味着什么都没有<代码>加载数据是加载大量数据的首选工具,如果可以使用的话。OP在评论中确认,解决方案需要使用Java。当然,我不认为这样做是可能的!但它只有在我不需要改变文件结构的时候才有用,对吗?是的。如果您需要对原始数据进行处理,那么使用Java可能是最好的方法。我知道没有答案,但我认为有可能做得更快,所以很可能我做错了。多线程可能对我来说太高了:)不过,谢谢你的回复,这是一个本地数据库
PreparedStatement prepStmt = con.prepareStatement("Insert query");
prepStmt.setString(1,parameter1);
prepStmt.addBatch();
// for next set of parameter
prepStmt.setString(1,parameter2);
prepStmt.addBatch();
int [] numUpdates=prepStmt.executeBatch()