管理大容量复制的批大小

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics 平台系统(PDW)

在大容量复制操作中,批的主要目的在于定义事务的范围。 如果没有设置批大小,则大容量复制函数会将整个大容量复制视为一个事务。 如果设置了批大小,则每个批构成一个事务,当批运行完成时,该事务也就被提交。

如果在没有指定批大小的情况下执行大容量复制并且遇到错误,则将回滚整个大容量复制。 恢复长时间运行的大容量复制可能需要花费很长的时间。 如果设置了批大小,则大容量复制将每个批视为一个事务并分别提交每个批。 如果遇到错误,只需回滚最后一个未完成的批。

此外,批大小还会影响锁定开销。 对 SQL Server 执行大容量复制时,可以使用bcp_control指定 TABLOCK 提示来获取表锁而不是行锁。 对于整个大容量复制操作而言,持有单个表锁的开销最小。 如果未指定 TABLOCK,则对各个行持有锁,并且在大容量复制操作期间维护所有锁的开销会导致性能降低。 由于仅在事务执行期间才持有锁,因而可以通过指定批大小来解决此问题,因为这样可以定期生成能够释放当前持有的锁的提交。

如果要大容量复制大量的行,构成批的行的数目会对性能产生显著影响。 建议采用的批大小取决于要执行的大容量复制的类型。

  • 批量复制到 SQL Server 时,请指定 TABLOCK 大容量复制提示并设置大批大小。

  • 如果不指定 TABLOCK,请将批大小限制为小于 1,000 行。

从数据文件批量复制时,通过在调用 bcp_exec之前使用 BCPBATCH 选项调用bcp_control来指定批大小。 使用bcp_bind和bcp_sendrow从程序变量批量复制时,批大小由调用 bcp_sendrow x 次后调用bcp_batch来控制,其中 x 是批中的行数。

除了指定事务大小之外,批还会影响将行通过网络发送到服务器的时间。 大容量复制函数通常会从 bcp_sendrow 缓存行,直到填充网络数据包,然后将完整数据包发送到服务器。 但是,当应用程序调用 bcp_batch时,无论当前数据包是否已填充,都会发送到服务器。 使用很小的批大小可能导致向服务器发送许多部分填满的数据包,从而降低性能。 例如,在每次bcp_sendrow调用bcp_batch会导致每一行都发送在单独的数据包中,除非行非常大,否则会浪费每个数据包中的空间。 SQL Server 的网络数据包的默认大小为 4 KB,不过应用程序可以通过调用 指定SQL_ATTR_PACKET_SIZE属性的 SQLSetConnectAttr 来更改大小。

批处理的另一个副作用是,每个批被视为未完成 的结果集,直到完成bcp_batch。 如果在批处理未完成时尝试对连接句柄执行任何其他操作,SQL Server Native Client ODBC 驱动程序会发出错误,SQLState = “HY000”和错误消息字符串为:

"[Microsoft][SQL Server Native Client] Connection is busy with  
results for another hstmt."  

另请参阅

执行大容量复制操作 (ODBC)
大容量导入和导出数据 (SQL Server)