【问题标题】:JDBC batch execution guaranteesJDBC 批处理执行保证
【发布时间】:2020-05-05 14:20:53
【问题描述】:

我们正在尝试在 Azure Synapse(以前称为 Azure SQL 数据仓库)中执行批量插入。问题是:

  • 性能极差(插入一行小于 2KB 和 20-25 列的行大约需要 1 秒)
  • 它是线性扩展的(我认为 100 行大约需要 90 秒)

我们使用标准 JDBC 批量插入模式 addBatch() & executeBatch() 和 PreparedStatements (https://stackoverflow.com/a/3786127/496289)。

我们使用的是微软提供的 JDBC 驱动。

我们知道出了什么问题,在 DB 遥测中,很明显 DB 正在分解批处理并且或多或少地像在 for 循环中一样运行它。没有批量“优化”。

奇怪的是,当底层数据源是 SQL Server 时,批处理会按预期进行。

问题是: 标准/规范中是否没有规定 executeBatch() 应该比线性扩展更好?

例如JDBC™ 4.3 Specification (JSR 221) 说它可以提高性能,而不是必须。

第 14 章批量更新

批量更新工具允许一次将多个 SQL 语句提交到数据源进行处理。提交多个 SQL 语句,而不是单独提交,可以大大提高性能。 Statement、PreparedStatement 和 CallableStatement 对象可用于提交批量更新

14.1.4 PreparedStatement Objects 没有明确/暗示的声明来说明批处理机制是为了获得更好的性能。


可能应该补充一点,Azure Synapse 能够在 17-26 分钟内使用 500 个 DWU 从数据湖加载 1 万亿行数据(Parquet 格式约为 450 GB)。

【问题讨论】:

  • 好吧,你没有告诉我们你观察到的性能没有批次(使用单个 PreparedStatement 插入)。使用批处理的主要区别在于为每个插入的行保存 往返。恕我直言,好消息是,即使您观察到在数据库中重复单行插入,这也不能解释每行经过一秒的时间。所以必须有其他(可能是微不足道的)解释。
  • @MarmiteBomber,没有批处理它是 ~1 秒/行。 --So there must be an other (probale trivial) explanation:不完全是,我们已经进行了广泛的测试/调试,Azure 已经举手表示这是预期的。所以没有琐碎或非琐碎的解释,这只是表现。在问题底部添加另一个关于性能的声明。

标签: performance jdbc azure-sql-data-warehouse


【解决方案1】:

JDBC 规范不需要对批处理执行进行任何类型的优化。事实上,并不是所有的数据库都支持批量执行。无论底层数据库系统是否支持,都希望符合标准的 JDBC 驱动程序实现批量执行。

如果数据库系统不支持,JDBC驱动会通过循环重复执行语句来模拟批量执行。这样的实现不会比手动重复执行语句更好。

这也是为什么你引用的文字说“可以大大提高性能”而不是将或必须.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    相关资源
    最近更新 更多