当前位置: 首页 > 面试题库 >

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

吕霍英
2023-03-14
问题内容

我试图用大约50,000行10列填充Java中的resultSet,然后使用的batchExecute方法将它们插入到另一个表中PreparedStatement

为了使过程更快,我进行了一些研究,发现在将数据读入resultSet时,fetchSize起着重要的作用。

如果fetchSize太低,可能会导致到服务器的行程过多,而fetchSize太高则会阻塞网络资源,因此我做了一些尝试,并设置了适合我的基础结构的最佳大小。

我正在阅读此resultSet并创建insert语句以插入到另一个数据库的另一个表中。

这样的事情(只是一个示例,不是真实的代码):

for (i=0 ; i<=50000 ; i++) {
    statement.setString(1, "a@a.com");
    statement.setLong(2, 1);
    statement.addBatch();
}
statement.executeBatch();
  • executeBatch方法会尝试一次发送所有数据吗?
  • 有没有一种方法可以定义批量大小?
  • 有没有更好的方法来加快批量插入的过程?

批量更新(50,000行10列)时,最好将可更新的ResultSet或PreparedStaement用于批处理?


问题答案:

我会依次解决您的问题。

  • executeBatch方法会尝试一次发送所有数据吗?

对于每个JDBC驱动程序,这可能会有所不同,但是我研究的少数驱动程序将遍历每个批处理条目,并每次将参数与准备好的语句句柄一起发送给数据库以执行。也就是说,在上面的示例中,将执行50,000条带有50,000对参数的已准备好的语句,但是这50,000个步骤可以在较低级别的“内部循环”中完成,这是节省时间的地方。颇为夸张的类比,这就像退出“用户模式”进入“内核模式”并在那里运行整个执行循环。您可以为每个批次条目节省进出该较低级别模式的潜水成本。

  • 有没有一种方法可以定义批量大小

您已经在这里隐式定义了它,方法是在通过执行批处理之前将50,000个参数集推入Statement#executeBatch()。批大小为1同样有效。

  • 有没有更好的方法来加快批量插入的过程?

考虑在批量插入之前显式打开事务,然后再提交。不要让数据库或JDBC驱动程序在批处理中的每个插入步骤周围施加事务边界。您可以使用Connection#setAutoCommit(boolean)方法控制JDBC层。首先使连接脱离
自动提交模式
,然后填充批次,启动事务,执行批次,然后通过提交事务Connection#commit()

该建议假定您的插入不会与并发编写器竞争,并且假定这些事务边界将为您提供从源表中读取的足够一致的值以用于插入。如果不是这种情况,则主张正确性胜于速度。

  • 使用可更新的ResultSet还是PreparedStatement批量执行的更好?

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

同样,只要我们不讨论 特定的
JDBC驱动程序,就应该考虑这些答案的一般性和推测性。每个驱动程序的复杂程度各不相同,并且每个驱动程序在追求的优化方面也各不相同。



 类似资料:
  • 我有一个脚本可以插入大量的数据。此数据主要是前一个insert的复制,但至少有一个值不同。因此,我准备语句并绑定参数以执行和重复。 我现在使用的代码(一次全部大容量插入): 我想要实现的是,数据将用像上面这样的准备好的语句插入,但每个批处理的限制是1000(或任何其他数字)。我不能让这件事发生。我尝试使用和其他方法,但无法使其工作。

  • 问题内容: 使用JDBC(Oracle),我需要在两个表的每一个中插入大约一千行。像这样: 问题在于两个表都是通过公共序列连接的,因此语句的顺序很重要。 如果我只有一张桌子,那会很容易。在这种情况下,我使用了代码: 但是,这种方法只能用一个准备好的语句,因此只能用一个插入。我该如何解决这个问题? 问题答案: 你可以试试 然后

  • 我有一个遗留代码,不允许使用预先准备好的语句。它使用Spring JDBC和更新查询。要求更新100000行。我有一张地图,上面有行号和需要在特定列中更新的值。 下面是我的当前代码: 我需要将其更改为批量执行,以便在for循环之后,我可以在一次DB命中中执行它。 对于这个需求,使用spring JDBC批处理更新的最佳方式是什么?

  • 问题内容: 如何批量更新mysql数据?如何定义这样的事情: 具有一些值,例如: 和其他值: 也许用mysql是不可能的?一个PHP脚本? 问题答案: 在这种情况下,最简单的解决方案是使用构造。它的工作速度非常快,并且可以轻松完成工作。 或使用建筑

  • 我有一个将列名映射到值的。要更新的列事先未知,在运行时决定。 例如< code>map = {col1: "value1 ",col2: "value2"}。 我想执行一个< code>UPDATE查询,用这些列将表更新为相应的值。我能做以下事情吗?如果没有,有没有一种优雅的方法可以不用手动构建查询?

  • 我在调试中不断看到这个错误。登录cassandra, 在这个里面 因此,根据Cassandra中的这个标签,https://github . com/krasserm/akka-persistence-Cassandra/issues/33,我看到这是由于输入有效负载大小的增加,所以我将cassandra.yml中的< code > commit log _ segment _ size _ in