3

下面是示例查询,考虑 A

INSERT INTO Target (Col1,Col2,Col3,Col4) ----------------Statement#1
Select A.Col1,B.Col2,A.Col3,C.Col4       ----------------Statement#2
FROM A WITH(NOLOCK) INNER JOIN B WITH(NOLOCK)
    ON A.Id = B.ID
    LEFT JOIN C WITH NOLOCK
    ON C.Id = B.ID
Where A.Id = 11

在哪个阶段将锁应用于表[排他锁?],SQL 将如何执行查询?

  1. 将根据 join 和 where 子句从表 A、B 和 C 中获取结果。
  2. 在准备好的结果上,开始在表中插入数据并同时对表应用锁。

因此,当实际数据写入页表时,即使它是 INSERT INTO 和 SELECT,但在选择期间不会被锁定?

4

2 回答 2

2

这两个步骤是查询执行的逻辑步骤。SQL Server 在物理级别可以做什么/做什么是另一回事。此刻:

INSERT INTO Target (Col1,Col2,Col3,Col4) ----------------Statement#1
Select A.Col1,B.Col2,A.Col3,C.Col4       ----------------Statement#2
FROM A WITH(NOLOCK) INNER JOIN B WITH(NOLOCK)
    ON A.Id = B.ID
    LEFT JOIN C WITH NOLOCK
    ON C.Id = B.ID
Where A.Id = 11

对于每个输出记录(请参阅SELECT子句),它需要X lock一个RID或一个KEY内目标表(RID用于堆/KEY用于聚集索引)并插入该记录。对每个输出记录重复此步骤。因此,它不会从源表中读取所有记录,并且仅在此步骤之后才开始将记录插入目标表中。由于NOLOCK源表上的表提示,它只需要对这些表进行 Sch-S(模式稳定性)锁定。

如果你想在目标表上使用 X 锁,那么你可以使用

INSERT INTO Target WITH(TABLOCKX) (Col1,Col2,Col3,Col4)
SELECT ...

如果您想要最少记录的插入,请阅读这篇文章

于 2013-09-13T07:09:15.053 回答
0

您是否指定了任何“表锁定”提示。如果要行级锁定 将“表锁定”设置为关闭。

或者检查一下它会帮助你......

http://technet.microsoft.com/en-us/library/ms180876(v=sql.105).aspx

于 2013-09-13T06:24:44.333 回答