Sql server 了解SELECT查询上的SQL Server锁

Sql server 了解SELECT查询上的SQL Server锁,sql-server,tsql,linq-to-sql,Sql Server,Tsql,Linq To Sql,我想知道如果影响表的其他查询只有SELECT查询,那么在表上使用SELECT WITH(NOLOCK)有什么好处 SQL Server是如何处理的?SELECT查询是否会阻止另一个SELECT查询 我正在使用SQL Server 2012和Linq to SQLDataContext (编辑) 关于性能: 如果使用锁定的选择,第二个选择是否必须等待第一个选择完成 与使用(NOLOCK)选择的相比 选择无锁-将选择可能/可能不会插入的记录。您将读取脏数据 例如,假设一个事务插入1000行,然后失

我想知道如果影响表的其他查询只有
SELECT
查询,那么在表上使用
SELECT WITH(NOLOCK)
有什么好处

SQL Server是如何处理的?
SELECT
查询是否会阻止另一个
SELECT
查询

我正在使用SQL Server 2012和Linq to SQL
DataContext

(编辑)

关于性能:

  • 如果使用锁定的
    选择
    ,第二个
    选择
    是否必须等待第一个
    选择
    完成
  • 与使用(NOLOCK)选择的
    相比

选择无锁-将选择可能/可能不会插入的记录。您将读取脏数据

例如,假设一个事务插入1000行,然后失败


当您选择-时,您将获得1000行。

在我的工作中,我们有一个非常大的系统,可以同时在多台PC上运行,具有数十万行的非常大的表,有时甚至数百万行

当您在一个非常大的表上进行选择时,假设您想知道用户在过去10年中进行的每个事务,并且表的主键没有以有效的方式构建,那么查询可能需要几分钟的时间来运行

然后,我们的应用程序可能会让我同时在多个用户的PC上运行,访问同一个数据库。因此,如果有人试图插入到另一个SELECT正在读取的表中(在SQL试图读取的页面中),则可能会发生锁定,两个事务会相互阻塞

我们不得不在SELECT语句中添加一个“无锁”,因为这是一个表上的巨大SELECT,同时被很多用户使用,而且我们一直都有锁


我不知道我的例子是否足够清楚?这是一个真实的例子。

SQL Server中的
SELECT
将在表行上放置一个共享锁,而第二个
SELECT
也需要一个共享锁,并且它们彼此兼容

因此,没有一个
SELECT
不能阻止另一个
SELECT

使用带有(NOLOCK)查询提示的
,是为了能够读取正在插入(由另一个连接插入)但尚未提交的数据

如果没有该查询提示,
SELECT
可能会被正在进行的
INSERT
(或
UPDATE
)语句阻止读取表,该语句会对行(或可能是整个表)进行独占锁定,直到提交(或回滚)该操作的事务为止

WITH(NOLOCK)
提示的问题是:您可能正在读取最终根本不会插入的数据行(如果
INSERT
事务回滚),因此您的例如报告可能会显示从未真正提交到数据库的数据


还有另一个查询提示可能对(readpass)
有用。这将指示
SELECT
命令跳过它试图读取且以独占方式锁定的任何行。
SELECT
不会阻塞,也不会读取任何“脏”未提交的数据-但它可能会跳过某些行,例如不显示表中的所有行。

关于性能,您一直关注SELECT。
共享不阻止读取。
共享锁块更新。
如果您有数百个共享锁,则需要更新一段时间才能获得独占锁,因为它必须等待共享锁清除

默认情况下,选择(读取)采用共享锁。
共享锁允许并发事务读取(选择)资源。
共享锁对其他选择没有影响(1或1000)

区别在于nolock与sharedlock如何影响更新或插入操作

当资源上存在共享锁时,其他事务无法修改数据

共享锁阻止更新
但nolock不会阻止更新

这会对更新的性能产生巨大影响。它还影响插入件

脏读(nolock)听起来很脏。你永远不会得到部分数据。如果一个更新把约翰变成了莎莉,你永远也不会高兴

我经常使用共享锁来实现并发性。数据一读就过时了。在接下来的几毫秒内,约翰变成了萨利,这是过时的数据。萨莉在下一毫秒被约翰回滚的读数是陈旧数据。这是毫秒级的。我有一个数据加载器,如果用户使用共享锁,则需要20小时运行,如果用户不使用锁,则需要4小时运行。在这种情况下,共享锁会导致数据过期16小时

不要错误地使用NOLOCK。但他们确实有自己的位置。如果要在将字节设置为1时剪切检查,然后在剪切检查时将其设置为2—这不是nolock的时间。

选择(nolock)允许读取未提交的数据,这相当于在数据库上设置了
读取未提交的
隔离级别。与在整个数据库上设置隔离级别相比,
NOLOCK
关键字允许更细粒度的控制

维基百科有一篇有用的文章:


其他stackoverflow文章也详细讨论了这一点。

我必须补充一条重要的评论。每个人都提到,
NOLOCK
只读取脏数据。这并不准确。也可能在读取过程中两次获取同一行或跳过整行。原因是,当SQL Server重新平衡b树时,您可以同时请求一些数据

检查其他线程

)

通过NOLOCK提示(或将会话的隔离级别设置为READ UNCOMMITED),您可以告诉SQL Server您不期望一致性,因此没有任何保证。记住,“不一致的数据”不仅仅意味着你