2012-01-05 75 views
8

我正在使用Apache Derby存储数百万的数量级的大量行。每次我开始批量插入时,我都会在表格中插入多达2百万行。 该表具有作为其主键的UUID和与另一个表中的UUID的单个约束。 插入需要几个小时!为什么? 我已经在所有的表上创建了INDEXs,但是我已经删除了这个,因为我相信Derby会为每个包含主键的表自动创建一个INDEX。 我使用与准备语句批处理更新如图所示(在下面非常简单的形式)阿帕奇德比插入缓慢

final PreparedStatement addStatement = connection.prepareStatement(...) 
int entryCount = 0; 
    for (final T entry : entries) { 
    addStatement.addBatch(); 
    entryCount++; 
    if (entryCount % 1000 == 0) { 
    addStatement.executeBatch(); 
    addStatement.clearBatch(); 
    entryCount = 0; 
    } 
addStatement.close(); 

下面是结果

05/01/12 12:42:48 Creating 2051469 HE Peaks in DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 12:44:18 Progress: Written (10%) 205146/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 12:46:51 Progress: Written (20%) 410292/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 12:50:46 Progress: Written (30%) 615438/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 05/01/12 12:56:46 Progress: Written (40%) 820584/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:04:29 Progress: Written (50%) 1025730/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:13:19 Progress: Written (60%) 1230876/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:22:54 Progress: Written (70%) 1436022/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:34:53 Progress: Written (80%) 1641168/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:47:02 Progress: Written (90%) 1846314/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:58:09 Completed: Written (100%) 2051469/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE - Time Taken:01:15:21 

正如我插入越来越多的行,则处理变慢并较慢(可能是因为INDEX)。我现在的数据库模型很好地服务于我的目的,我不愿意改变它。 我做错了什么? ...或期待太多? 有什么办法来提高INSERT速度?


编辑

我已经使用自动提交和其他调整的DB。我发现,当INSERT数百万条记录时 - 它确实会为我的应用程序花费不合理的时间。选择这些数据当然非常快。

+0

您知道您可以使用Derby将数据保留在磁盘上,并且可以从最后一个记录ID加载远程数据? _(对不起,很明显。)_ – 2013-09-02 16:16:55

回答

8

您是否试过关闭自动提交模式?从http://db.apache.org/derby/docs/dev/tuning/tuningderby.pdf

插入在自动提交模式下可能会很痛苦,因为每个提交都会为每个INSERT语句更新磁盘上的日志的 。直到 执行物理磁盘写入,提交才会返回。为了加快速度:在自动提交虚假模式

  • 运行,在一个事务中执行多个刀片,并 然后明确地发出一个承诺。
  • 如果您的应用程序允许初始加载到表中,则可以使用导入 过程将数据插入表中。当使用这些接口将 加载到空表中时,德比将不会记录单个插入。有关 导入过程的更多信息,请参阅Derby参考手册 手册和Derby服务器和管理指南。
+0

感谢您的回复。我已经使用自动提交和其他方式调整了数据库。我发现,当INSERT数百万条记录时 - 它确实会为我的应用程序花费不合理的时间。选择这些数据当然非常快。我不得不重构我的数据库,使用ProtocolBuffers编写对象集合,工作得非常好,而且速度非常快 - 唯一的问题是每当我想使用数据时都必须加载整个对象集合 - 但这对我来说是足够的。 – 2012-02-29 09:42:22

+0

@AndyTudor - 你可以解释一下:“我不得不重构我的数据库,使用ProtocolBuffers编写对象集合,工作得非常好,而且速度非常快 - 唯一的问题是我每次想使用时都要加载整个对象集合数据”。我面临类似的挑战,并想知道这是我能做的事情。 – donlys 2016-12-15 16:02:22