在 INSERT 上使用 WITH TABLOCK 的好处

Mar*_*man 19 performance sql-server insert sql-server-2012

在某些情况下,INSERT INTO <tablename> (WITH TABLOCK)由于日志记录最少,执行 an会更快。这些情况包括将数据库置于BULK_LOGGED恢复模型中。

是否有任何其他潜在的性能优势,使用WITH TABLOCKINSERT的空白表时,数据库(tempdb数据库)使用SIMPLE恢复模式?

我正在使用 SQL Server 2012 标准版。

我的用例是在使用 的存储过程中创建然后立即填充临时表INSERT...SELECT,其中可能包含多达几百万行。我尽量避免这种tempdb滥用,但有时需要这样做。

我正在尝试构建一个需要 require 的案例TABLOCK。它似乎不会伤害任何东西,并且可能有好处。我试图弄清楚是否有足够的潜在好处将它添加到我们的代码库中的任何地方,我确信没有其他进程想要写入表。

我通常使用集群 PK 插入新创建的本地临时表,但有时会使用堆。

Joe*_*ish 20

我知道一些好处,但它们主要是根据情况而定的。

  1. 使用TABLOCK将减少并发但会立即在目标表上获取表锁。只要您能保证只有一个会话将插入到表中,这将避免不必要的行或页锁并防止锁升级。毕竟,如果您插入了如此多的数据以至于无论如何都会导致锁升级,为什么不提前做呢?
  2. 如果您在没有TABLOCK所有页面的情况下插入一个空的页面压缩堆,则将进行行压缩而不是页面压缩

新插入的行是页面压缩的:

  • 如果新行转到带有页面压缩的现有页面

  • 如果新行是通过 BULK INSERT 和 TABLOCK 插入的

  • 如果通过 INSERT INTO ... (TABLOCK) SELECT FROM 插入新行

否则,该行是行压缩的。

  1. 在 SQL Server 2016 中,TABLOCK需要提示并行插入CCI(集群列存储索引)本地临时表。有很多限制,其中一些没有记录。不能有IDENTITY列,不能通过 插入OUTPUT,等等。

另请参阅数据加载性能指南