Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中最高效的多线程数据库插入_Java_Database_Performance_Sqlite_Jdbc - Fatal编程技术网

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

Java中最高效的多线程数据库插入,java,database,performance,sqlite,jdbc,Java,Database,Performance,Sqlite,Jdbc,我们必须将大量数据从HDD(~50GB)读取到数据库中,但我们的多线程过程非常慢(~10GB为~2h),因为org.sqlite.core.NativeDB.reset[native](请参阅线程采样器) 我们读取数据的速度相对较快,并使用insert方法执行准备好的语句。但只有我们收集了大约50万个数据集,我们才能将所有这些语句提交到数据库中。目前,我们使用JDBC作为sqlite数据库的接口 如果您总共使用一个线程,那么到目前为止一切都正常。但是,如果您想使用多个线程,您不会看到性能/速度有

我们必须将大量数据从HDD(~50GB)读取到数据库中,但我们的多线程过程非常慢(~10GB为~2h),因为
org.sqlite.core.NativeDB.reset[native]
(请参阅线程采样器)

我们读取数据的速度相对较快,并使用insert方法执行准备好的语句。但只有我们收集了大约50万个数据集,我们才能将所有这些语句提交到数据库中。目前,我们使用
JDBC
作为
sqlite
数据库的接口

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

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

(螺纹名称为1,2,…,15)

}

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

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();
}
}


大多数数据库都有某种大容量插入功能,尽管目前还没有相应的标准

例如,Postrgresql有副本,MySql有加载数据。 不过,我不认为SQLite有这种功能——可能值得切换到有这种功能的数据库。

SQLite


加载大量数据的最快方法是使用单个线程(和单个事务)将所有内容插入数据库(而不是使用WAL)。

我记得SQLite本身一次只允许一个操作。@Andreas我们存储所有插入内容,然后一次提交500k。批处理没有带来重大改进:(你在插入之前删除了索引吗?@YCF\u L我们将根据提供的示例再次尝试批处理。谢谢!你是说批处理,即用
addBatch()
替换
executeUpdate()
,然后对
addBatch()的每1000多次调用执行
executeBatch()
,不会提高性能吗?我发现这是不太可能的,除非性能瓶颈主要在其他方面,例如插入的表上的索引过多。提交间隔与此关系不大。有什么建议吗?您可以在JDBC中使用此类功能,还是在编程语言中使用老化还是仅直接在数据库服务器上?看起来您可以使用来自jdbc的Postgresql副本-请参阅
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)