【发布时间】:2010-12-01 08:14:16
【问题描述】:
我对 BOL 短语感到困惑:
“不能为插入、更新或删除操作修改的表指定 READUNCOMMITTED 和 NOLOCK。SQL Server 查询优化器忽略 FROM 子句中适用于 UPDATE 或 DELETE 语句的目标表的 READUNCOMMITTED 和 NOLOCK 提示” [一]
例如,如果我写
--script 1)
UPDATE Test SET Txt=(Select Txt from TEST WITH(NOLOCK) where ID=1)
WHERE ID=1
它运行时没有错误(或警告),可能相当于
--script 2)
set transaction isolation level SERIALIZABLE;
begin tran
Declare @nvarm nvarchar(max);
Select @nvarm=Txt from Test where ID=1;
--Select @nvarm;
UPDATE Test SET Txt=@nvarm WHERE ID=1;
commit;
它也可以在没有错误或警告的情况下运行。
是否等效?
表是相同的,但在 FROM 中它在逻辑上是源表而不是目标表 我可以用不同的源表重写 1) 作为另一个(物理)表:
--script 3)
select *
into testDup
from TEST;
GO;
UPDATE Test SET Txt=(SELECT Txt FROM TestDUP WITH(NOLOCK) where ID=1)
WHERE ID=1
为什么要在另一个表上忽略 NOLOCK?
或者,如果错了,那就提问
如何编写具有“适用于 UPDATE 或 DELETE 语句的目标表的 FROM 子句中的 NOLOCK 提示”的 UPDATE,因为即使在 1)和 2)中,物理表也是相同的,但在逻辑上是源(在 SELECT 中)表和目标(在 UPDATE 中)表是不同的。
如何编写一个 UPDATE 语句来证明 WITH(NOLOCK) 被忽略?
为什么要完全忽略它?会被忽略吗?
或者,如果这是一个错误的问题,那么
为什么语法允许保证被忽略的提示?
再一次,要么不可能(或者是吗?)写出文档中写的这样的声明,要么我不理解“忽略”的含义(忽略它的意义是什么?或让它在全部?)...
更新2:
答案表明,NOLOCK 在 UPDATE 语句的 FROM 子句中未被(更新)忽略,BOL 文档 [1] 断言。
嗯,这个问题的本质:
你能给我任何例子(上下文),在 UPDATE 语句的 FROM 子句中忽略 NOLOCK 是有意义的吗?
[1]
表提示 (Transact-SQL)
SQL Server 2008 R2
http://msdn.microsoft.com/en-us/library/ms187373.aspx
【问题讨论】:
标签: sql sql-server tsql database-design query-hints