优化批量插入,SQLite
我正在使用不同的缓冲区大小插入到本地SQLite DB中,并发现当缓冲区大小为10,000时,插入10,000,000行数据需要将近8分钟。 换句话说,它需要1,000次写入来存储所有内容。
存储10,000,000的8分钟似乎有点太长(或者是吗?)
以下任何一项都可以进行优化以提高速度吗? 请注意,插入的数据是随机的字符集合。
public int flush() throws SQLException { String sql = "insert into datastore values(?,?,?,?);"; PreparedStatement prep = con.prepareStatement(sql); for (DatastoreElement e : content) { // content is 10,000 elements long _KVPair kvp = e.getKvp(); prep.setInt(1, e.getMetaHash()); prep.setInt(2, kvp.hashCode()); prep.setString(3, kvp.getKey()); prep.setString(4, kvp.getValue()); prep.addBatch(); } int[] updateCounts = prep.executeBatch(); con.commit(); return errorsWhileInserting(updateCounts); }
创建表时,它通过完成
statement.executeUpdate("create table datastore (meta_hash INTEGER," + "kv_hash INTEGER," + "key TEXT," + "value TEXT);");
可以进一步优化上述任何一项吗?
我对Java API有点模糊,但我认为你应该首先启动一个事务,否则调用commit()
是没有意义的。 使用conn.setAutoCommit(false)
。 否则,SQLite将为每个插入/更新进行日志记录。 这需要同步文件,这将导致缓慢。
编辑:提问者更新说,这已经设置为真。 在这种情况下:
这是很多数据。 这段时间听起来不是这个世界。 您可以做的最好的事情是使用不同的缓冲区大小进行测试。 它们之间的缓冲抖动太小而虚拟内存在大尺寸的情况下会有平衡。 因此,您不应该尝试将其全部放入一个缓冲区中。 将插入物拆分成您自己的批次。
您只执行一次executeBatch
,这意味着在executeBatch
调用中将所有1000万个语句发送到数据库。 这对于数据库来说太过分了。 你还应该执行int[] updateCounts = prep.executeBatch();
在你的循环中,让我们说所有1000行。 只需创建一个if语句,对counter % 1000 == 0
进行测试。 然后,数据库可以异步处理您发送的数据。
- 如何通过XSLT合并Java中的2个XML流
- 每个vs常规的Java – 它们是等价的吗?
- Mockito – 存根方法时的NullpointerException
- .jfindClass中的错误(as.character(driverClass)):找不到类
- 如何使用hibernate生成Custom Id,同时它必须是表的主键
- Java:在播放音乐的JFrame上绘制随机形状
- 在Eclipse Oxygen中更改Project Explorer树视图字体大小
- 如何在Tomcat 5.5.x中进行EJB 3.1部署
- java.lang.ClassNotFoundException:org.springframework.web.servlet.DispatcherServlet错误