我使用Mysql开发了一个Java 1.7项目,
我有一个使用PreparedStatement在表中插入大量数据的方法,但这会在GlassFish服务器中导致内存不足错误。
Connection c = null;
String query = "INSERT INTO users.infos(name,phone,email,type,title) "
+ "VALUES (?, ?, ?, ?, ?, ";
PreparedStatement statement = null;
try {
c = users.getConnection();
statement = c.prepareStatement(query);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try{
int i =0;
for(Member member: members){
i++;
statement.setString(1, member.getName());
statement.setString(2, member.getPhone());
statement.setString(3, member.getEmail());
statement.setInt(4, member.getType());
statement.setString(5, member.getTitle());
statement.addBatch();
if (i % 100000 == 0){
statement.executeBatch();
}
}
statement.executeBatch();
}catch (Exception ex){
ex.printStackTrace();
} finally {
if(c != null)
{
try {
c.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
c = null;
statement = null;
}我认为我需要创建一个存储过程来避免这个内存问题,但我不知道从哪里开始,是否应该创建一个过程或函数,以及我是否能够在返回或其他方面得到某种响应?
你觉得那个怎么样?
发布于 2016-08-23 23:22:34
将预准备语句中的insert语句替换为对预准备语句中的存储过程的调用不会以任何有意义的方式影响内存消耗。
内存不足,因为您使用的批处理大小非常大。您应该测试不同批处理大小的性能-您会发现,当批处理大小超过几十到数百个时,较大批处理的性能改进很快就会减弱。
通过使用load data infile,您可以获得更高的输入速率。您将获取多行数据,创建一个文本文件并加载该文件。例如,请参见this question。
你也可以考虑并行化。例如,打开多个连接,并使用单独的线程向每个连接插入行。同样,您可以尝试使用load data infile进行并行加载。
您必须在您的硬件设置上尝试各种技术、批处理大小、线程数量(可能每个内核不超过一个)等,以查看哪些技术提供最佳性能。
您可能还希望考虑调优一些MySQL参数、删除(并在稍后重新创建)索引等。
https://stackoverflow.com/questions/39104851
复制相似问题