我看过使用nolock和(nolock)的sql语句 例如 -
select * from table1 nolock where column1 > 10
和
select * from table1 with(nolock) where column1 > 10
以上哪项陈述是正确的,为什么?
答案 0 :(得分:29)
第一个语句没有锁定任何东西,而第二个语句没有。刚刚在SQL Server 2005上测试了这个,在
中select * from table1 nolock where column1 > 10 --INCORRECT
“nolock”成为table1中查询的别名。
select * from table1 with(nolock) where column1 > 10
执行所需的nolock功能。持怀疑态度?在单独的窗口中,运行
BEGIN TRANSACTION
UPDATE tabl1
set SomeColumn = 'x' + SomeColumn
锁定表,然后在自己的窗口中尝试每个锁定语句。第一个将挂起,等待锁被释放,第二个将立即运行(并显示“脏数据”)。不要忘记发出
ROLLBACK
当你完成。
答案 1 :(得分:18)
已弃用的功能列表位于Deprecated Database Engine Features in SQL Server 2008:
- 指定NOLOCK或READUNCOMMITTED 在UPDATE或的FROM子句中 DELETE语句。
- 指定表格 不使用WITH关键字的提示。
- HOLDLOCK表提示没有 括号
- 在表格提示之间使用空格作为分隔符。
- 通过视图间接应用表提示到多语句表值函数(TVF)的调用。
它们都在SQL的下一个版本之后有时会删除的功能列表中,这意味着只有在较低的数据库兼容级别下才能在enxt版本中支持它们。
据说我在问题上的2c是这样的:
from table nolock
和from table with(nolock)
都错了。如果您需要脏读,则应使用适当的transaction isolation级别:set transaction isolation level read uncommitted
。通过这种方式,所使用的关联级别可以通过一个“旋钮”进行明确说明和控制,而不是通过源传播并受制于表提示的所有怪癖(通过视图和TVF等间接应用)。脏读是一种不合理的行为。在99.99%的情况下,需要的是减少争用,而不是读取未提交的数据。通过针对设计良好的架构编写适当的查询来减少争用,并在必要时通过部署快照隔离来减少争用。解决工作的最佳解决方案几乎总能保存一些极端情况,是数据库中的enable read commited snapshot并让引擎发挥其魔力:
ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
然后从选择中删除所有提示。
答案 2 :(得分:6)
它们在技术上都是正确的,但是从SQL 2005开始not using the WITH keyword has been deprecated,所以习惯使用WITH关键字 - 简答题,使用WITH关键字。
答案 3 :(得分:5)
使用“WITH(NOLOCK)”。
答案 4 :(得分:0)
两者在语法上都是正确的。
NOLOCK将成为table1的别名。
WITH(NOLOCK)经常被用作加速数据库读取的神奇方法,但我尽量避免使用它。
结果集可以包含尚未提交的行,这些行通常会在以后回滚。
错误或结果集可以为空,缺少行或多次显示同一行。
这是因为其他交易在您阅读的同时正在移动数据。
READ COMMITTED增加了一个额外的问题,即单个列中的数据被破坏,其中多个用户同时更改同一个单元格。
还有其他副作用,导致牺牲你希望首先获得的速度增加。
现在你知道了,再也不用了。