刚开始工作的时候经常听同事说在SQL码表后面加上WITH(NOLOCK)会更好。经过仔细的研究和测试,我终于知道为什么了。那么加和不加有什么区别呢?SQL每次创建一个新的查询,就相当于创建一个会话。不同查询窗口的操作会影响其他会话的查询。当一个表在写数据的时候,很可能这个时候查询会一直阻塞,即使你只是一个很简单的SELECT,也会一直等待。这里我们使用事务向某个表写入数据和从某个表写入数据。我们知道事务在写表后必须提交(COMMIT)或者回滚(ROLLBACK)才能释放表,否则会一直处于阻塞状态。在插入过程中,我们写一个简单的查询语句,看看不加WITH(NOLOCK)和加WITH(NOLOCK)会发生什么。示例数据如下表A所示,这是我们创建的一个非常简单的表。接下来,我们创建一个事务以将数据写入其中(使用BEGINTRAN启动一个事务)。我们发现有1行受到影响,注意这里的sessionID是59(左上角黄色标签上的数字)。在不加NOLOCK的情况下,我们新建一个查询窗口,然后查询A表:从上面的查询可以看出,A表被锁住了,我们的查询已经被阻塞了。这里sessionid为60,此时如果在session59的窗口执行COMMIT或ROLLBACK,会立即显示session60的查询结果,这里我们后面的演示不commit或rollback。添加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)和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)
