该文档列出了具有最少日志记录的批量导入的以下要求
- 数据库的恢复模式设置为简单或批量日志。
- 目标表是空堆或非空堆。
- 复制时不使用目标表。
- TABLOCK 提示是为目标表指定的。
(强调我的)。
请注意,上面都没有提到 B 树。尽管如此,我的经验和 Iztik Ben-Gann 的T-Sql 查询书都声称空的TABLOCK
ed B 树将获得批量插入。
INSERT INTO [...] WITH (TABLOCK)
在堆上运行时是否比在 B 树上运行时有更强的最小日志记录保证?如果不是,那么我无法理解为什么文档似乎对 B 树行为保持沉默。
看看这是否提供了更多上下文:https://learn.microsoft.com/en-us/sql/relational-databases/import-export/precessions-for-minimal-logging-in-bulk-import ?view=sql-服务器版本16
文档可能强调堆的行为,因为它们更有可能从批量插入上下文中的最少日志记录中受益。相反,聚集索引
(B-trees)
本质上具有更复杂的结构,并且即使使用TABLOCK
.SQL Server 中批量插入期间最小日志记录的行为取决于多个因素,包括聚集索引的存在以及表是空还是非空:
堆(空或非空): 当使用 插入空堆时
TABLOCK
,SQL Server 可以使用最少的日志记录,即使数据库不处于BULK_LOGGED
或SIMPLE
恢复模式中。这是因为数据被附加到文件末尾,并且不需要每行都有单独的日志记录。当使用 插入非空堆时TABLOCK
,也会使用最小日志记录。但是,如果需要将数据插入到堆中间,则可能会由于页面拆分而产生一些额外的日志记录。聚集索引(B 树): 如果目标表有空聚集索引,则数据页和索引页都会被最小化记录。这意味着只会生成所使用范围的分配页和最少日志记录,从而减少日志记录。但是,如果表具有基于 B 树的聚集索引并且非空,则无论恢复模型如何,数据页和索引页都会被完全记录。这是因为插入非空聚集索引涉及重新排列现有数据以维持排序顺序,这需要额外的日志记录。
该文档强调,使用空聚集索引时,数据和索引页都会被最少地记录,从而提供了一种在减少日志记录的情况下执行批量插入的有效方法。此行为特定于聚集索引和空表的组合。
虽然
TABLOCK
可以减少堆和聚集索引的日志记录,但这种行为对于堆来说更为明显,尤其是当堆为空时。对于聚集索引,由于索引结构的原因可能会有额外的日志记录。