REORGANIZE INDEX 阻止其他查询

Bri*_*ian 0 sql-server azure-sql-database

(在 Azure 中运行的 SQL Server 12.0.2000.8)

我的理解是 REORGANIZE 索引不应该干扰其他操作(也就是说,它不应该阻止对正在进行索引重组的表的查询,当然也不应该阻止对其他表的查询)。但是,我有一个夜间索引维护作业,它似乎在运行时阻塞了其他查询。

导致阻塞的查询格式为:

ALTER INDEX [indexName] ON tableName REORGANIZE
Run Code Online (Sandbox Code Playgroud)

它导致其他查询等待,即使是简单的查询,例如:

SELECT * FROM tableName WHERE indexedColumn = @value
Run Code Online (Sandbox Code Playgroud)

我使用该sp_who2过程来查看哪些查询正在等待,以及它们被哪些其他查询阻止。再一次,正在进行索引维护的表和 SELECT 中的表完全不相关(它们甚至在不同的模式中;FWIW 被重组的表在 中dbo)。

被重组的表有近 5 亿行。受影响的索引是外键使用的单个 bigint 列上的非聚集、非唯一索引。表本身由两个 bigint 列、一个 tinyint 和几个小 nvarchars 组成。

看起来没什么特别的,但我不明白为什么它会阻止其他查询。是否有一些我遗漏的隐藏依赖?

For*_*est 5

不幸的是,您的理解是一种误解,REORGANIZE 需要锁定才能运行。它只是没有像离线 REBUILD 那样严重的锁定。

由于 REORGANIZE 需要 X 锁,因此它有可能阻塞读取器。

这是一个快速演示来证明它需要锁定。

DROP TABLE IF EXISTS dbo.whyreorg

CREATE TABLE dbo.whyreorg
(ID INT IDENTITY PRIMARY KEY, junk INT)

INSERT dbo.whyreorg
SELECT TOP 1000 FLOOR(RAND(CONVERT(VARBINARY,NEWID()))*1000)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b

CREATE INDEX IX_whyreorg_this ON dbo.whyreorg (junk)

BEGIN TRAN
ALTER INDEX IX_whyreorg_this ON dbo.whyreorg REORGANIZE

SELECT *
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID

COMMIT
Run Code Online (Sandbox Code Playgroud)

示例输出(为空间修剪): REORGANIZE 的锁

REORGANIZE 不应该锁定其他表,因此我会根据正在进行重组的表假设被阻止的事务中的某些内容。没有细节,无法证实这一点。

值得庆幸的是,这里的解决方案很简单:停止重组。