`

SQL 2005 with(nolock)详解

 
阅读更多
    大家在写查询时,为了性能,往往会在表后面加一个nolock,或者是with(nolock),其目的就是查询是不锁定表,从而达到提高查询速度的目的。

什么是并发访问:同一时间有多个用户访问同一资源,并发用户中如果有用户对资源做了修改,此时就会对其它用户产生某些不利的影响,例如:

1:脏读,一个用户对一个资源做了修改,此时另外一个用户正好读取了这条被修改的记录,然后,第一个用户放弃修改,数据回到修改之前,这两个不同的结果就是脏读。

2:不可重复读,一个用户的一个操作是一个事务,这个事务分两次读取同一条记录,如果第一次读取后,有另外用户修改了这个数据,然后第二次读取的数据正好是其它用户修改的数据,这样造成两次读取的记录不同,如果事务中锁定这条记录就可以避免。

3:幻读,指用户读取一批记录的情况,用户两次查询同一条件的一批记录,第一次查询后,有其它用户对这批数据做了修改,方法可能是修改,删除,新增,第二次查询时,会发现第一次查询的记录条目有的不在第二次查询结果中,或者是第二次查询的条目不在第一次查询的内容中。

为什么会在查询的表后面加nolock标识?为了避免并发访问产生的不利影响,SQL Server有两种并发访问的控制机制:锁、行版本控制,表后面加nolock是解决并发访问的方案之一。

1> 锁,每个事务对所依赖的资源会请求不同类型的锁,它可以阻止其他事务以某种可能会导致事务请求锁出错的方式修改资源。当事务不再依赖锁定的资源时,锁将被释放。

锁的类型:1:表类型:锁定整个表;2:行类型:锁定某个行;3:文件类型:锁定某个数据库文件;4:数据库类型:锁定整个数据库;5:页类型:锁定8K为单位的数据库页。

锁的分类还有一种分法,就是按用户和数据库对象来分:

1). 从数据库系统的角度来看:分为独占锁(即排它锁),共享锁和更新锁

1:共享 (S) :用于不更改或不更新数据的操作(只读操作),一般常见的例如select语句。

2:更新 (U) :用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。

3:排它 (X) :用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。

2). 从程序员的角度看:分为乐观锁和悲观锁。

1:乐观锁:完全依靠数据库来管理锁的工作。

2:悲观锁:程序员自己管理数据或对象上的锁处理。

一般程序员一看到什么锁之类,觉的特别复杂,对专业的DBA当然是入门级知识了。可喜的是程序员不用去设置,控制这些锁,SQLServer通过设置事务的隔离级别自动管理锁的设置和控制。锁管理器通过查询分析器分析待执行的sql语句,来判断语句将会访问哪些资源,进行什么操作,然后结合设定的隔离级别自动分配管理需要用到的锁。

2>:行版本控制:当启用了基于行版本控制的隔离级别时,数据库引擎 将维护修改的每一行的版本。应用程序可以指定事务使用行版本查看事务或查询开始时存在的数据,而不是使用锁保护所有读取。通过使用行版本控制,读取操作阻止其他事务的可能性将大大降低。也就是相当于针对所有的表在查询时都会加上nolock,同样会产生脏读的现象,但差别在于在一个统一管理的地方。说到了基于行版本控制的隔离级别,这里有必要说下隔离级别的概念。

隔离级别的用处:控制锁的应用,即什么场景应用什么样的锁机制。

最终目的:解决并发处理带来的种种问题。

隔离级别的分类:

1:未提交读,隔离事务的最低级别,只能保证不读取物理上损坏的数据;

2:已提交读,数据库引擎的默认级;

3:可重复读;

4:可序列化;隔离事务的最高级别,事务之间完全隔离。

小结:NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED事务隔离级别 。nolock确实在查询时能提高速度,但它并不是没有缺点的,起码它会引起脏读。

nolock的使用场景(个人观点):

1:数据量特别大的表,牺牲数据安全性来提升性能是可以考虑的;

2:允许出现脏读现象的业务逻辑,反之一些数据完整性要求比较严格的场景就不合适了,像金融方面等。

3:数据不经常修改的表,这样会省于锁定表的时间来大大加快查询速度。

综上所述,如果在项目中的每个查询的表后面都加nolock,这种做法并不科学,起码特别费时间,不如行版本控制来的直接有效。而且会存在不可预期的技术问题。应该有选择性的挑选最适合的表来放弃共享锁的使用。

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

1:SQL05中的同义词,只支持with(nolock);

2:with(nolock)的写法非常容易再指定索引。

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

SQL code

select * from [IP].a.dbo.table1 with (nolock) 这样会提示用错误select * from a.dbo.table1 with (nolock) 这样就可以
分享到:
评论

相关推荐

    EFCore.SqlServer.WithNoLock

    EFCore.SqlServer.WithNoLock

    sqlserver中with(nolock)深入分析

    处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAST,本文将介绍有关 NOLOCK 和 READPAST的一些技术知识点,需要的朋友可以参考下

    SQL Server的WITH (NOLOCK)

    缺点:  1.会产生脏读  2.只适用与select查询语句  优点:  1.有些文件说,加了WITH (NOLOCK)的SQL...其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询的环

    sql server 性能优化之nolock

    其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询的环境中数据集被LOCK的现象藉此改善查询的效能。  不过有一点千万要注意的就是,WITH (NOLOCK)的SQL SELECT...

    Laravel开发-nolock

    Laravel开发-nolock 读取Laravel和Laravel使用联盟文件系统的方式中的锁定文件

    hibernate SQLServer2008Dialect

    SQLServer2008Dialect 优化了原来的分页查询数据方法以及在生成SQL时表后增加了with(nolock)

    SQLServer2008Dialect

    SQLServer2008Dialect 优化了原来的分页查询数据方法以及在生成SQL时表后增加了with(nolock)

    微软内部资料-SQL性能优化3

    An intent lock indicates that SQL Server wants to acquire a shared (S) lock or exclusive (X) lock on some of the resources lower down in the hierarchy. For example, a shared intent lock placed at the ...

    全国身份证+车牌+省市表

    SELECT ca.code,ca.name,ca.ParentCode,az.name,az.latitude,az.longitude FROM CarArea ca WITH(NOLOCK) LEFT JOIN ( SELECT * FROM AreaZoon WITH(NOLOCK) WHERE parentCode='0' ) az ON az.proshortname=ca....

    C语言算法(nolock)

    C语言算法(nolock)这本书非常详细的讲解了C语言常用到的算法,了解了算法的本质。

    在SQL Server中迁移数据的几种方法

    DTS的设计器功能强大,支持多任务,也是可视化界面,容易操作,但知道的人一般不 多,如果只是进行SQL Server数据库中部分表的移动,用这种方法最好,当然,也可以进行全部表的移动。在SQL Server Enterprise ...

    【微软SQL2008精编】

    select * from dbo.UserInfo with (nolock) HOLDLOCK 持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放 NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED事务隔离级别

    SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法

    代码如下:SET @SQL = ‘SELECT * FROM Comment with(nolock) WHERE 1=1 And (@ProjectIds Is Null or ProjectId = @ProjectIds) And (@Scores is null or Score =@Scores)’ 印象中记得,以前在做Oracle开发时,...

    使用正则表达式匹配tsql注释语句

    代码如下:–获取表的count信息select count(*) from T with(nolock) –获取特定值的count信息select count(*) from T with(nolock)where v = ‘–value’ –获取表’T’的count信息select count(*) from T with...

    错误信息:select error:由于数据移动,未能继续以NOLOCK方式扫描 脚本文件

    适用于思迅全系列商业进销存软件,在使用软件过程中,在做数据汇总,或者数据日结中如果提示这个错误后,把软件退出,用查询分析器执行此脚本,重新运行软件,就可以解决这个问题,不同的软件替换下对应的数据库名称...

    Sqlserver死锁处理(比较好用)

    /**//*--调用示例 exec p_lockinfo 0,1 --*/ create proc p_lockinfo @kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉...@show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示

    SQL Server中发送HTML格式邮件的方法

    sql server 发送html格式的邮件,参考代码如下: ... -- 获取当前系统时间,和数据统计的时间 set @d_nowdate = convert... if exists (select top 1 * from t_table1(nolock) where d_rq=@d_nowdate) begin set @str_

    经量级的ORM开发框架CRL

    效率问题:在对象映射上作了缓存处理,查询效率几乎等于手写SQL效率,注:CRL对象查询默认是 with(nolock) 数据安全:所有标准查询都经过参数化处理,无注入风险 动态存储过程支持与查询转换,极大减少了数据库维护工作,...

Global site tag (gtag.js) - Google Analytics