刚开始工作的时候,经常听同事说在SQL代码的表后面加上WITH(NOLOCK)会好一些,后来仔细研究测试了一下,终于知道为什么了。
那么加与不加到底有什么区别呢?
SQL在每次新建一个查询,就相当于创建了一个会话。在不同的查询窗口操作,会影响到其他会话的查询。当某张表正在写数据时,这时候去查询很可能就会一直处于阻塞状态,哪怕你只是一个很简单的SELECT也会一直等待。
我们这里使用事务来往某张表里写数据,我们知道事务在写完表必须提交(COMMIT)或回滚(ROLLBACK)才能释放表,否则会一直处于阻塞状态。
在插入过程中,我们写一个简单的查询语句,在不添加WITH(NOLOCK)和添加WITH(NOLOCK)的情况下,看会发生什么。
如下表A,是我们新建的一个非常简单的表。

下面我们创建一个往里面写数据的事务(使用BEGIN TRAN就可以开始一个事务了)

我们发现有1行受影响了,注意这里的会话ID是59(左上角黄色标签上的数字)
我们新建一个查询窗口,然后查询A表

从上面的查询可以看到,表A被锁住了,我们的查询一直处于阻塞状态。这里的会话ID是60
这个时候如果你在会话59的窗口执行COMMIT或ROLLBACK,会话60的查询结果会立刻显示出来,这里为了下面的演示我们暂时不提交或回滚。
我们再新建一个查询窗口,还是查询A表,这次我们加上NOLOCK。

注意上图标红色的地方,当前会话ID是55,旁边的60还在执行状态,而我们加了NOLOCK后,瞬间就查询出结果了,而且还把事务里即将要插入的数据给查询到了。这是为什么呢?
事务里的数据虽然还没有提交,但是它实际上已经存在内存里面了,这个时候我们使用NOLOCK查询到的结果,实际上还没存储到硬盘。
从上面的两个测试可以看出,NOLOCK的作用其实就是为了防止查询时被阻塞,只是这样会产生脏读(未提交的数据)。
那么一般什么情况下使用NOLOCK呢?
通常是一些被频繁写的表,不管是插入,更新还是删除。这样的表在查询时,使用NOLOCK是非常有效的。
WITH(NOLOCK)和NOLOCK的区别
不知道小伙伴注意没,我前面介绍时是写的WITH(NOLOCK),但是测试时,使用的是(NOLOCK),它们有什么区别呢?
为了搞清楚WITH(NOLOCK)与NOLOCK的区别,我们先看看下面三个SQL语句有啥区别
SELECT * FROM A NOLOCK
SELECT * FROM A (NOLOCK);
SELECT * FROM A WITH(NOLOCK);(NOLOCK)这样的写法,NOLOCK其实只是别名的作用,而没有任何实质作用。所以不要粗心将(NOLOCK)写成NOLOCK
(NOLOCK)与WITH(NOLOCK)其实功能上是一样的。(NOLOCK)只是WITH(NOLOCK)的别名,但是在SQL Server 2008及以后版本中,(NOLOCK)不推荐使用了,"不借助 WITH 关键字指定表提示”的写法已经过时了。
在使用链接服务器的SQL当中,(NOLOCK)不会生效,WITH(NOLOCK)才会生效。
--这样会提示用错误
select * from [IP].[dbname].dbo.tableName with (nolock)
--这样就可以
select * from [dbname].dbo.tableName with(nolock)类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or