sql查询,nolock写还是不写,这是一个问题
在做过的很多项目中,发现大家不管对什么表,逢select必定加上nolock(或者with(nolock)),好像已经是制度化的一种东西。有领导高人解释说加上nolock可以提高查询速度,不影响对数据表的其他并发操作。
但是真有必要每个查询都加nolock吗?个人认为加不加nolock还是值得我们根据实际情况斟酌一番的(至少需要知其然然后知其所以然吧)。下面就来简单分析一下加不加nolock以及加了nolock对实际查询的一些影响。
一、重要概念
(此处沉思5秒,安静回想经典数据库教科书里的一些重用概念。嗯......什么,你也想不全了?那好吧,别闲烦,道理是要讲的,书是不得不参考的(bs直接抄书的))
并发访问:同一时间有多个用户访问同一资源。如果并发用户中有其他用户同时对资源进行了修改,这样对同一数据的访问就会出现“所见不是所得”的情况,从而对其它用户产生某些不利的影响,包括:
1:脏读:有一个用户对某一个资源做了修改,此时另外一个用户正好读取了这条被修改的记录,然后第一个用户又放弃了修改,数据还原到修改之前,这两个不同的结果就是脏读。
2:幻读:特指用户读取一批记录的情况。用户两次查询同一条件的一批记录,第一次查询后,有其它用户对这批数据做了修改,方法可能是insert,update或delete,第二次查询时,用户会发现第一次查询的记录条目有的不在第二次查询结果中,或者是第二次查询的条目不在第一次查询的内容中,造成前后查询结果的不一致。
3:不可重复读:系统中某一个用户的一个操作是一个事务,这个事务分两次读取同一条记录。如果第一次读取后,正好有另外一个用户修改了这条记录,然后第二次读取的正好是之前进行修改记录的那位用户的数据,这样就有可能造成两次读取的数据不同。当然如果我们在事务中锁定这条记录就可以避免。
二、如何消除并发访问的不利影响
如前所述,既然并发访问会造成这么多不利影响,我们又该如何解决呢?估计一般程序员的下意识反应就是像我们在控制多线程并发编程的时候一样,加锁,lock一下,over。没错,还真不能说你说的不对!真是聪明又幸福的程序员啊!
其实在ms的Sql Server中,有两种并发访问的控制机制:锁和行版本控制,关于并发控制,ms的阐述和解决方案真是详细而周到。你不得不pf我们的ms是多么的亲妈啊,真的什么都帮我们想好并且做好了。
先分析一下数据库的锁。
小抄一段参考书上的:
1、锁:“每个事务对所依赖的资源会请求
相关文档:
SQL版:
alter proc testguo
(
@cityid int,
@cityname nvarchar(100) output
)
as
select @cityname = city_name from BA_Hot_City where cityid = @cityid
select @cityname
go
declare @cityname nvarchar(100)
exec testguo 1,@cityname output
另一版:
ht ......
Student(S#,Sname,Sage,Ssex) 学生表
Course(C#,Cname,T#) 课程表
SC(S#,C#,score) 成绩表
Teacher(T#,Tname) 教师表
问题:
1、查询“001”课程比“002”课程成绩高的所有学生的学号;
select a.S# from (select s#,score from SC where C#='001') a,(select s#,score
fr ......
配置sql server 2000以允许远程访问适合故障:1. 用sql企业管理器能访问sql server 2000(因为它是采用命名管道(named pipes)方式进行方式),但用ado.net 方式(udp)不能访问.2. 采用ado.net方式不能远程访问.故障的可能原因有:1.sql server 2000没有安装sql server 2000 sp3a及以上升级包,还未启用并开放1433端口(udp);2 ......
Student(S#,Sname,Sage,Ssex) 学生表
Course(C#,Cname,T#) 课程表
SC(S#,C#,score) 成绩表
Teacher(T#,Tname) 教师表
问题:
1、查询“001”课程比“002”课程成绩高的所有学生的学号;
select a.S# from (select s#,score from SC where C#='001') a,(select s#,score
fr ......