Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.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_Resultset_Bulkinsert_Prepared Statement - Fatal编程技术网

使用准备好的语句在Java中批量插入批更新

使用准备好的语句在Java中批量插入批更新,java,resultset,bulkinsert,prepared-statement,Java,Resultset,Bulkinsert,Prepared Statement,我试图用Java填充一个结果集,其中包含大约50000行10列 然后使用PreparedStatement的batchExecute方法将它们插入到另一个表中 为了加快进程,我做了一些研究,发现在将数据读入resultSet时,fetchSize起着重要作用 非常低的fetchSize可能会导致到服务器的访问次数过多,而非常高的fetchSize可能会阻塞网络资源,因此我进行了一些尝试,并设置了一个适合我的基础架构的最佳大小 我正在阅读这个结果集并创建insert语句以插入到另一个数据库的另一个

我试图用Java填充一个结果集,其中包含大约50000行10列 然后使用
PreparedStatement
batchExecute
方法将它们插入到另一个表中

为了加快进程,我做了一些研究,发现在将数据读入resultSet时,fetchSize起着重要作用

非常低的fetchSize可能会导致到服务器的访问次数过多,而非常高的fetchSize可能会阻塞网络资源,因此我进行了一些尝试,并设置了一个适合我的基础架构的最佳大小

我正在阅读这个结果集并创建insert语句以插入到另一个数据库的另一个表中

类似这样的内容(只是一个示例,不是真正的代码):


for(i=0;i如果它只是数据库中一个或多个表中要插入到此表中的数据,并且没有干预(对结果集的更改),则调用
statement.executeUpdate(SQL)
要执行station,这会更快,因为没有开销。没有数据超出数据库,整个操作都在数据库上,而不是在应用程序中。

批处理将在“一次完成”——这是您要求它执行的操作

在一次呼叫中尝试50000似乎有点大。我会将其分解为1000个较小的块,如下所示:

final int BATCH_SIZE = 1000;
for (int i = 0; i < DATA_SIZE; i++) {
  statement.setString(1, "a@a.com");
  statement.setLong(2, 1);
  statement.addBatch();
  if (i % BATCH_SIZE == BATCH_SIZE - 1)
    statement.executeBatch();
}
if (DATA_SIZE % BATCH_SIZE != 0)
  statement.executeBatch();
final int BATCH_SIZE=1000;
对于(int i=0;i

50000行不会超过几秒钟。

我将依次回答您的问题

  • executeBatch方法是否会尝试一次发送所有数据
这可能因每个JDBC驱动程序而异,但我所研究的少数几个驱动程序每次都会迭代每个批处理条目,并将参数与准备好的语句句柄一起发送到数据库以供执行s可以在较低级别的“内部循环”中完成,这是节省时间的地方。作为一个相当长的类比,这就像从“用户模式”下降到“内核模式”并在那里运行整个执行循环。您可以为每个批处理条目节省跳入和跳出该较低级别模式的成本

  • 有没有办法定义批量大小
您在这里通过
语句#executeBatch()
在执行批处理之前推入50000个参数集来隐式定义它。一个批处理大小同样有效

  • 有没有更好的方法来加速批量插入过程
考虑在批插入之前显式打开事务,然后提交。不要让数据库或JDBC驱动程序在批中的每个插入步骤周围强加事务边界。您可以使用该方法控制JDBC层。首先将连接从自动提交模式中移除,然后填充批,然后再重新启动rt事务,执行批处理,然后通过提交事务

此建议假设您的插入不会与并发编写器发生冲突,并假设这些事务边界将为您提供从源表读取的足够一致的值,以便在插入中使用。如果情况并非如此,请支持正确性而不是速度

  • 使用可更新的
    ResultSet
    PreparedStatement
    批执行是否更好
没有什么比使用您选择的JDBC驱动程序测试更好的了,但我希望后者-
PreparedStatement
Statement\executeBatch()
会在这里胜出。语句句柄可能有一个关联的“批处理参数”列表或数组每个条目都是调用
语句#executeBatch()
语句#addBatch()
(或
语句#clearBatch()
)之间提供的参数集。该列表将随着每次调用
addBatch()
而增长,直到调用
executeBatch()时才会刷新
。因此,
语句
实例实际上起到了参数缓冲区的作用;为了方便起见,您正在交换内存(使用
语句
实例代替您自己的外部参数集缓冲区)


再一次,只要我们不讨论一个特定的JDBC驱动程序,就应该考虑这些答案的一般性和推测性。每个驱动程序的复杂程度各不相同,每一个都会改变它所追求的优化。

批量unLogud更新不会给您改进的性能。在我的问题中,我将插入到不同数据库中的不同表中,因此插入选择是不可能的,因为我没有任何指向源的DBlinks谢谢,我将按照你的建议这样做,但这将是我的最后一个选项,我在JDBC API中寻找一些内置功能,在那里我可以设置某种批量大小就像我们在批量读取时设置Fetch大小一样,如果没有,那么为什么不为批处理执行提供批处理大小,而是允许为批处理提供FetchSizereading@Bohemian,数据大小的理想值是多少?@bindumalink根据我的经验,10K是一个很好的起点。要调整它,请不断提高它,直到它开始ops工作可靠,然后使用该值的一半。谢谢,非常有趣的指针。这无疑提高了我对JDBC的理解。我将从这里开始,进行一点实验

final int BATCH_SIZE = 1000;
for (int i = 0; i < DATA_SIZE; i++) {
  statement.setString(1, "a@a.com");
  statement.setLong(2, 1);
  statement.addBatch();
  if (i % BATCH_SIZE == BATCH_SIZE - 1)
    statement.executeBatch();
}
if (DATA_SIZE % BATCH_SIZE != 0)
  statement.executeBatch();