gpt4 book ai didi

java - Java 中最高效的多线程数据库插入

转载 作者:行者123 更新时间:2023-12-02 13:15:26 26 4
gpt4 key购买 nike

我们必须将大量数据从 HDD (~50GB) 读取到数据库中,但由于 org.sqlite.core.NativeDB.reset[native] 内部存在线程锁,我们的多线程过程非常慢(~10GB 需要约 2 小时)。 (请参阅线程采样器)。

我们相对快速地读取数据并使用插入方法来执行准备好的语句。但只有当我们收集了大约 500.000 个数据集时,我们才会将所有这些语句提交到我们的数据库中。目前我们使用JDBC作为我们的 sqlite 的接口(interface)数据库。

如果您总共使用一个线程,到目前为止一切正常。但是,如果您想使用多个线程,您不会看到性能/速度有太大提高,因为一次只能运行一个线程,而不是并行运行。我们已经重复使用了 preparedStatement并且所有线程都使用我们的 Database 类的一个实例来防止文件锁定(有一个到数据库的连接)。

不幸的是,我们不知道如何进一步改进我们的插入方法。有谁能够给我们一些提示/解决方案或如何不使用此 NativeDB.reset 方法的方法?我们不必使用 SQLite,但我们想使用 Java。

ThreadMonitor (线程被命名为 1,2,...,15)

Thread Sampler

Resource Usage

private String INSERT = "INSERT INTO urls (url) VALUES (?);";

public void insert(String urlFromFile) {
try {
preparedStatement.setString(1, urlFromFile);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}

}

按照@Andreas的建议更新了插入方法,但它仍然抛出一些异常

public void insert(String urlFromFile) {
try {
preparedStatement.setString(1, urlFromFile);
preparedStatement.addBatch();
++callCounter;
if (callCounter%500000 == 0 && callCounter>0){
preparedStatement.executeBatch();
commit();
System.out.println("Exec");
}
} catch (SQLException e) {
e.printStackTrace();
}

}

java.lang.ArrayIndexOutOfBoundsException: 9
at org.sqlite.core.CorePreparedStatement.batch(CorePreparedStatement.java:121)
at org.sqlite.jdbc3.JDBC3PreparedStatement.setString(JDBC3PreparedStatement.java:421)
at UrlDatabase.insert(UrlDatabase.java:85)

最佳答案

大多数数据库都有某种批量插入功能,尽管没有标准,据我所知。

例如,Postrgresql 有 COPY,MySql 有 LOAD DATA。不过,我认为 SQLite 没有这种功能 - 可能值得切换到具有这种功能的数据库。

关于java - Java 中最高效的多线程数据库插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43791951/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com