可用版本:Dev (3.21) | 最新版 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

节流

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

当导入大型数据集时,显式定义每个数据的最佳大小可能是有益的

  • 批量大小: 在一个 SQL 语句中发送到服务器的行数。默认为 1。
  • 批处理大小: 在一个 JDBC 语句批处理中发送到服务器的语句数量。默认为 1。
  • 提交大小: 在一个事务中提交的语句批处理数量。默认为 1。

所有三种类型的限制都可以组合使用。

并非所有 RDBMS 都提供相同的优化功能。请参阅您的数据库手册,了解这些调整功能可能如何影响您的数据导入性能。此外,实际测量可能有助于改进这些数字。不要过早优化或基于假设进行优化。始终测量您的优化是否具有期望的效果!

批量大小

批量数据处理在 SQL 中非常重要,SQL 是一种基于集合的语言。也可以使用 INSERT .. VALUESINSERT .. SELECT 来表达批量 INSERT 语句。复杂的 RDBMS 可能会使用这些语句来改进磁盘块分配过程,因为如果一个 INSERT 语句有多于 1 行,优化器会更好地了解存储传入数据需要多少空间。此方法还有助于“聚簇”插入的数据(将同时插入的数据保存在本地磁盘块“群集”中),如果以后经常读取相同的数据,这可能是有益的。虽然在 SSD 或其他随机访问磁盘上的好处可能很小,但在 HDD 上可能很显著。

有 3 种可能的互斥配置来指定批量大小

create.loadInto(BOOK)

      // Put all the data in a single bulk statement.
      .bulkAll()

      // Put up to 32 rows in a single bulk statement.
      .bulkAfter(32)

      // Do not put more than 1 row in a statement.
      .bulkNone()

      .loadCSV(inputstream)
      .fields(BOOK.ID, BOOK.AUTHOR_ID, BOOK.TITLE)
      .execute();

批处理大小

批处理数据处理允许减少网络流量开销,因为它允许 JDBC 驱动程序缓冲多个后续语句执行的绑定值,并将它们一次性发送。

有 3 种可能的互斥配置来指定批处理大小

create.loadInto(BOOK)

      // Execute all statements (bulk or not) in a single large statement batch.
      .batchAll()

      // Put up to 32 statements (bulk or not) in a single statement batch.
      .batchAfter(32)

      // Execute each statement (bulk or not) individually.
      .batchNone()

      .loadCSV(inputstream)
      .fields(BOOK.ID, BOOK.AUTHOR_ID, BOOK.TITLE)
      .execute();

提交大小

如果提交事务过于频繁或不够频繁,提交事务可能是一项昂贵的操作。如果提交次数过多,可能会导致服务器上大量的日志记录开销。如果太多的更改在未提交状态下保留太长时间,则在 2PL 事务模型中可能会有太多的锁定,或者在 MVCC 事务模型中可能存在日志争用。经验证的最优提交大小(例如提交 1000 行(或 10000 行,或 100 行,请测量最适合您的)可能会产生最佳结果。

有 3 种可能的互斥配置来指定批处理大小

create.loadInto(BOOK)

      // Commit all statements (batch, bulk, or not) in a single large transaction.
      .commitAll()

      // Put up to 32 statements (batch, bulk, or not) in a transaction.
      .commitAfter(32)

      // Commit each statement (batch, bulk, or not) in a transaction, just like commitAfter(1)
      .commitEach()

      // Do not commit any statement, leave committing to client code
      .commitNone()

      .loadCSV(inputstream)
      .fields(BOOK.ID, BOOK.AUTHOR_ID, BOOK.TITLE)
      .execute();

反馈

您对此页面有任何反馈吗? 我们很乐意听到您的反馈!

The jOOQ Logo