刚开始工作的时候经常听同事说在SQL码表后面加上WITH(NOLOCK)会更好。经过仔细的研究和测试,我终于知道为什么了。那么加和不加有什么区别呢?SQL每次创建一个新的查询,就相当于创建一个会话。不同查询窗口的操作会影响其他会话的查询。当一个表在写数据的时候,很可能这个时候查询会一直阻塞,即使你只是一个很简单的SELECT,也会一直等待。这里我们使用事务向某个表写入数据和从某个表写入数据。我们知道事务在写表后必须提交(COMMIT)或者回滚(ROLLBACK)才能释放表,否则会一直阻塞。在插入过程中,我们写一个简单的查询语句,看看不加WITH(NOLOCK)和加WITH(NOLOCK)会发生什么。示例数据如下表A所示,这是我们创建的一个非常简单的表。接下来,我们创建一个事务向其中写入数据(使用BEGINTRAN启动一个事务),我们发现有一行受到了影响。注意这里的sessionID是59(左上角黄色标签上的数字)没有加NOLOCK。新建一个查询窗口,然后查询A表。从上面的查询可以看出A表被锁住了,我们的查询已经被阻塞了。这里的sessionID是60,此时如果在session59的窗口执行COMMIT或ROLLBACK,会立即显示session60的查询结果。下面的演示,我们暂时不提交也不回滚。添加NOLOCK,我们新建一个查询窗口,或者查询A表,这次我们添加NOLOCK。注意图标上红色的地方,当前sessionID是55,旁边的60还在执行状态。我们加了NOLOCK之后,瞬间查询到了结果,同时查询到了事务中要插入的数据。为什么是这样?事务中的数据虽然没有提交,但实际存在于内存中。这时候我们使用NOLOCK查询的结果实际上还没有存储到硬盘中。从上面两个测试可以看出,NOLOCK的作用是防止查询被阻塞,但是这样会造成脏读(未提交数据)。那么什么情况下使用NOLOCK呢?通常是一些写入比较频繁的表,无论是插入、更新还是删除。在查询这样的表时,使用NOLOCK是非常有效的。不知道WITH(NOLOCK)和NOLOCK的区别,小伙伴们,你们注意到了吗?前面介绍的时候写的是WITH(NOLOCK),但是测试的时候用的是(NOLOCK)。它们之间有什么区别?为了理解WITH(NOLOCK)和NOLOCK的区别,我们先来看看下面三个SQL语句SELECT*FROMANOLOCKSELECT*FROMA(NOLOCK);的区别选择*来自AWITH(NOLOCK);(NOLOCK)这样写,NOLOCK其实只是一个别名,没有任何实际作用。所以不要粗心地写成(NOLOCK),因为NOLOCK(NOLOCK)和WITH(NOLOCK)实际上在功能上是一样的。(NOLOCK)只是WITH(NOLOCK)的别名,但在SQLServer2008及之后的版本中,不推荐使用(NOLOCK),“不使用WITH关键字指定表提示”的说法已经过时。在使用链接服务器的SQL中,(NOLOCK)不会生效,WITH(NOLOCK)才会生效。--这会提示你使用错误select*from[IP].[dbname].dbo.tableNamewith(nolock)--所以你可以select*from[dbname].dbo.tableNamewith(nolock)
