SqlServer2008R2在select时的with(nolock)选项说明

时间:2023-02-02 12:19:21
I used to see my senior developers use WITH (NOLOCK) when querying in SQL Server and wonder why they use. Now i explored it and found that it's useful to improve the performance in executing the query . However there is a disadvantage in using it. The disadvantage is that one may not be sure that they are getting the data which is currently being updated in the Table, ie, Without lock protection, you cannot be guaranteed that the data isn't changing during the time that the query is running. I referred this link and found it pretty useful.

要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑。其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询的环境中数据集被LOCK的现象藉此改善查询的效能。 不过有一点千万要注意的就是,WITH (NOLOCK)的SQL SELECT有可能会造成Dirty Read。例如:

select count(userid)
from employee with(nolock)
join working_group with(nolock)
on employee.userid = working_group.userid;

因为SQL Server会执行对应的锁定一致性检查。 欲改善整体数据库查询的效能,请将WITH (NOLOCK)加在您的SELECT语法中Table名称的后面,虽然(NOLOCK)也可以,但是微软还是建议大家要加WITH。

除了简单的SELECT之外,有JOIN的SELECT语法也是可以使用的。但是DELETE、INSERT、UPDATE这些需要transaction的指令就不行了…

有些文件说,加了WITH (NOLOCK)的SQL查询效率可以增加33%。

加了WITH (NOLOCK)即告诉SQL Server,我们的这段SELECT指令无需去考虑目前table的transaction lock状态,因此效能上会有明显的提升,而且数据库系统的Lock现象会有明显的减少(包含Dead Lock)。

有一点要特别注意,因为WITH (NOLOCK)不考虑目前table的transaction lock,因此当有某些资料正处于多个phase交易(例如跨多个table的transaction交易-->如提款系统),WITH (NOLOCK)会让目前处理交易process的数据被忽略…

讲白话一点,也就是说当使用NoLock时,它允许阅读那些已经修改但是还没有交易完成的数据。因此如果有需要考虑transaction事务数据的实时完整性时,使用WITH (NOLOCK)就要好好考虑一下。

如果不需考虑transaction,WITH (NOLOCK)或许是个好用的参考。

注1:WITH ( < table_hint > )指定由查询优化器使用的表扫描、一或多个索引,或由查询优化器利用此数据表以及为此语句使用锁定模式。

注2:WITH (NOLOCK)相当于READ UNCOMMITTED

最后说下nolock和with(nolock)的几个小区别:

1.SQL05中的同义词,只支持with(nolock);
2.with(nolock)的写法非常容易再指定索引。

跨服务器查询语句时 不能用with (nolock) 只能用nolock,同一个服务器查询时 则with (nolock)和nolock都可以用。比如:

select * from [IP].a.dbo.table1 with (nolock)

这样会提示用错误,使用下面的方式就不会:

select * from a.dbo.table1 with (nolock)