SQL Server 2012查询被LCK_M_IS阻塞

3

我很难理解以下两个查询如何会互相阻塞。

正在运行的查询(几乎可以是任何内容): 插入批量[Import].[WorkTable] ...

同时,我试图运行以下SELECT查询:

SELECT *
FROM    ( SELECT * FROM @indexPart ip
JOIN    sys.indexes i (NOLOCK)
    ON  i.object_id = ip.ObjectId
    and i.name = ip.IndexName) i
CROSS
APPLY   sys.dm_db_index_physical_Stats(db_id(), i.object_id,i.index_id,NULL,'LIMITED')  ps
WHERE   i.is_disabled = 0

第二个查询被第一个查询阻塞,并显示LCK_M_IS作为等待信息。重要的信息是,临时表@indexPart包含一个完全不同的表上索引的一条记录。我期望交叉应用程序尝试运行该单个索引的统计信息,而该索引与正在运行的其他查询无关。
谢谢。
编辑(新):
经过几次测试后,我认为自己找到了罪魁祸首,但仍然无法解释。
  1. 批量插入会话在表 [Import] .[WorkTable] 上拥有X锁。
  2. 上述查询正在检查表 [Import] .[AnyOtherTable] 上的索引,但是请求在 [Import] .[WorkTable] 上获得IS锁定。我一再验证上述查询(在没有交叉应用的情况下运行该内容)仅返回表[Import].[AnyOtherTable]上的一个索引。
  3. 现在,这里出现了魔法,将交叉应用程序更改为外部应用程序,就可以完全通过而没有任何锁定问题。
我希望有人能向我解释这个情况...

1
可能在元数据表上阻塞。查看阻塞时两个语句持有的所有锁的列表。 - usr
似乎第二个查询正在请求对两个系统表(sysidxstats、syssingleobjrefs)进行SCH_S锁定,这最终导致了阻塞。我很惊讶在sys.dm_db_index_physical_stats页面上找不到任何提及此事的内容。 - jimmy
1
@usr: http://stackoverflow.com/questions/7691580/deadlock-on-bulk-inserts 似乎表明批量插入可能会获取sch-m锁... - Ben Thul
@BenThul 是的,但那将是用户表上的SCH-M,而不是系统表。这可能是真正的原因。我有一种预感,OP误解了一些锁定信息。 - usr
谢谢大家的建议。我进行了更多的测试并检查了sp_lock的输出,并在我的原始帖子中添加了一个编辑! - jimmy
显示剩余2条评论
1个回答

1
问题可能出在您使用的where子句上。它应该在内联表中。以下更改可能会有所不同。
FROM    ( SELECT * FROM @indexPart ip
JOIN    sys.indexes i (NOLOCK)
ON  i.object_id = ip.ObjectId
and i.name = ip.IndexName
WHERE   i.is_disabled = 0) i

如果您这样做,可能会减少传递到交叉应用语句的记录数量。

SQL Server 会为您将谓词向内推。 - usr
没错,那不是问题。 - jimmy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接