我试图插入两百万行到MySQL表与批处理插入。以下是我的代码:
public void addItems(List<Item> Items) {
try {
conn = getConnection();
st = conn.prepareStatement(insertStatement);
for (Item item : items) {
int index = 1;
st.setString(index++, item.getA());
st.setString(index++, item.getB());
st.setLong(index++, item.getC());
st.setInt(index++, item.getD());
st.setFloat(index++, item.getE());
st.setInt(index++, item.getF());
st.setString(index++, item.getG());
st.setString(index++, item.getH());
st.addBatch();
}
st.executeBatch();
st.clearBatch();
}
}
我多次调用这个addItems()
函数(顺序地),每次调用传递不超过100个项。我观察到的是,这个addItems()
调用成功返回,我通过顺序调用addItems()
处理越来越多的数据(实际上所有的200万行),然后最后我的程序用OutOfMemoryException
崩溃,而我发现只有100行插入到表中,Java已经处理了200万行。我还将autoCommit
设置为true。
其他可能感兴趣的参数-
MySQLbuffer_pool_size =默认值(128 MB)log_file_size =默认值(5mb)
数据库连接字符串"jdbc:mysql://host:port/database?useServerPrepStmts=false&rewriteBatchedStatements=true"
我已经为Java进程分配了512MB的空间
最大连接数:10最小连接数:1
问题——
- 是一个异步的preparedStatement.executeBatch()调用操作或者MySQL连接器之前缓冲这些调用把它发送到数据库?
- 如何确保首先提交100行,然后处理下一组行是什么? 增加buffer_pool_size和log_file_size会帮助更快的插入吗?我没有访问DB主机,所以还没有尝试过。当我有权限时,我会尝试这个。
- 如何解决这个问题?
1。你总是可以通过代码来计算这样的东西。看看这里的源代码,第1443-1447行似乎答案是——视情况而定。例如,版本,或者如果批处理大小大于3(否则不值得这样做)。
4。在类似的情况下,我所做的是在每X行(假设为100行)之后执行批处理。