节流
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
当导入大型数据集时,显式定义每个数据的最佳大小可能是有益的
- 批量大小: 在一个 SQL 语句中发送到服务器的行数。默认为 1。
- 批处理大小: 在一个 JDBC 语句批处理中发送到服务器的语句数量。默认为 1。
- 提交大小: 在一个事务中提交的语句批处理数量。默认为 1。
所有三种类型的限制都可以组合使用。
并非所有 RDBMS 都提供相同的优化功能。请参阅您的数据库手册,了解这些调整功能可能如何影响您的数据导入性能。此外,实际测量可能有助于改进这些数字。不要过早优化或基于假设进行优化。始终测量您的优化是否具有期望的效果!
批量大小
批量数据处理在 SQL 中非常重要,SQL 是一种基于集合的语言。也可以使用 INSERT .. VALUES 或 INSERT .. 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();
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();
反馈
您对此页面有任何反馈吗? 我们很乐意听到您的反馈!