我想用超过5亿行填充数据库表,我有以下insert
方法:
public void insertRecord(Record rec) throws SQLException, ClassNotFoundException {
if (this.isTableExists(this.TABLE_NAME)) {
Connection conn = this.getConnection();
conn.setAutoCommit(true);
PreparedStatement ps = conn.prepareStatement("insert into "+this.TABLE_NAME+" ("+this.NODE_ID_COL+", "+this.LAT_COL+", "+this.LNG_COL+", "+this.XML_PATH_COL+") values (?, ?, ?, ?)");
ps.setString(1, rec.getNodeID());
ps.setString(2, rec.getLat());
ps.setString(3, rec.getLng());
ps.setString(4, rec.getPath());
ps.addBatch();
ps.executeBatch();
ps.close();
conn.close();
} else {
Log.e(TAG, "insertRecord", "table: ["+this.TABLE_NAME+"] does not exist");
}
}
我的问题是,因为我会插入大量的行:
答案 0 :(得分:5)
你的方法非常低效。 对于你的每条记录
PreparedStatement
相反,您应该保留一个PreparedStatement
并执行大小为50-100的批次。
之后,如果您知道自己在做什么,可以考虑使用多线程。多线程并不能让一切变得更快。
答案 1 :(得分:2)
在插入方法中,将记录数组保留为缓冲区。
在您说出100个项目后,创建一个PreparedStatement
,然后预约记录呼叫addBatch
。添加完所有记录后,请致电executeBatch
。
这将返回一个受影响记录的数组,每个批次调用的位置。
如果这还不够,那么您应该查看在队列中运行Executors
的{{1}},其中每个都是一次插入(或者甚至是其中几个插件)。< / p>
问题在于错误处理变得越来越复杂,所以尽量避免错误处理Runnables
。
同样使用多线程意味着执行是异步的,因此如果您有一个客户端等待响应,您需要仔细同步。