为什么NOLOCK查询提示是个不明智的想法
一些人总当NOLOCK查询提示是SQL Server里的加速器,因为它避免了大量的死锁情景。在这篇文章里,我想向你展示下为什么NOLOCK查询提示是个不好的想法。
脏读(Dirty Reads)
NOLOCK查询提示一个最大的副作用就是在你的记录集会出现所谓的脏读这个事实。我们来看下面的代码:
BEGIN TRANSACTION UPDATE Person.Person
SET FirstName = 'James'
WHERE LastName = 'Jones'
如你所见,我开始了一个新的事务,对AdventureWorks2012数据库里的Person.Person表进行UPDATE语句。现在当你尝试同时在另一个会话里读取这个记录时,这个SELECT语句会阻塞——在这个情况下请求的共享锁(S)会被已经授予的排它锁(X)阻塞——写阻塞读操作。
SELECT
FirstName,
LastName
FROM Person.Person
WHERE LastName = 'Jones'
GO
一些人现在回应用SQL Server里的加速器,使用NOLOCK查询提示:
SELECT
FirstName,
LastName
FROM Person.Person WITH (NOLOCK) -- It's a kind of magic...
WHERE LastName = 'Jones'
GO
如你所见死锁情景马上解决了,你从SQL Server返回记录了——遗憾的是在你面前现在有脏读(Dirty Read):你读取了尚未提交的数据。假设现在用UPDATE语句的第1个事务回滚了:在这个情况下,你已读取的数据在SQL Server里逻辑上是从未存在的。

因此NOLOCK查询提示并不是在每个情景都是有用的。 如果你想运行一个报表,或者你只想快速返回结果,记录不用100%正确,这“可以是”个可取的(考虑下一天的平均销售额)。当然,当你需要精确的结果,NOLOCK并不可取。当然也有一些特定场景即使NOLOCK也会阻塞。
读提交快照隔离(Read Committed Snapshot Isolation (RCSI))
有人给我提了为什么NOLOCK查询提示基本是一个不方便的(no-go)的选择:你不能在明显的方式里切换你的数据库查询到读提交快照隔离(Read Committed Snapshot Isolation (RCSI))。我从未想过这个情景,但没错是对的。读提交快照隔离(Read Committed Snapshot Isolation (RCSI))是个数据库选项。当你启用它的时候,每个查询都是在新的读提交快照乐观隔离级别里——只要在你的事务里不指定任何隔离级别。
对于特定的SQL语句使用NOLOCK查询提示,你临时修改隔离级别为未提交读(Read Uncommitted)。因此SQL语句也不会从读提交快照隔离受益,因为语句并没有在默认的提交读( Read Committed)隔离运行。这就对了!当你下次写下神奇的……WITH(NOLOCK)……时,好好想下这个额外参数。
小结
使用NOLOCK查询提示运行每个查询并不都有意义。一方面你会通过脏读(Dirty Reads)返回不一致的数据。另一方面你不能从读提交快照隔离(Read Committed Snapshot Isolation (RCSI))乐观隔离级别里受益,因为你临时修改了你SQL语句的默认隔离级别。
感谢关注!
参考文章:
https://www.sqlpassion.at/archive/2015/06/15/why-the-query-hint-nolock-is-a-bad-idea/
为什么NOLOCK查询提示是个不明智的想法的更多相关文章
- EntityFramework Core 3.x添加查询提示(NOLOCK)
前言 前几天看到有园友写了一篇关于添加NOLOCK查询提示的博文<https://www.cnblogs.com/weihanli/p/12623934.html>,这里呢,我将介绍另外一 ...
- sql 优化 链接提示 查询提示 标提示
SQL Server的查询优化器在select查询执行的时候产生一个高效的查询执行计划.如果优化器不能选择最优的计划,那么就需要检查查询计划.统计信息.支持的索引等,而通过使用提示可以改变优化器选择查 ...
- Sql Server优化之索引提示----我们为什么需要查询提示,Sql Server默认情况下优化策略选择的不足
环境: Sql Server2012 SP3企业版,Windows Server2008 标准版 问题由来: 最近在做DB优化的时候,发现一个存储过程有非常严重的性能问题, 由于整个SP整体逻辑是一个 ...
- SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)
前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...
- 利用查询提示优化SQL
数据库环境:SQL SERVER 2005 我们来看一下SQL语句及对应的数据量 SELECT COUNT(*) FROM cinvout_02 a WHERE ( a.dept_id IN ( SE ...
- MySQL查询提示
MySQL查询提示: 1.LOW_PROPRITY,HIGHT_PRIORITY 作用:指定sql语句的运行优先级,会将加了HIGHT_PROPRITY提示的sql调度到表访问队列的最前面 限制:仅对 ...
- MySQL自成一派的查询提示
[查询提示] MySQL中可以给select语句各种提示,比如告诉它“查询的结果集特别大,请直接用磁盘临时表”,“请让这条select优先执行” .... [查询提示:与结果集相关] 与结果集相关的查 ...
- SQL Server 调优系列玩转篇一(如何利用查询提示(Hint)引导语句运行)
前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...
- ECSHOP后台SQL查询提示错误 this sql May contain UPDATE,DELETE,TRUNCATE,ALTER,DROP,FLUSH,INSERT
一).首先说一下错误现象:市面上流行的绝大部分ECSHOP模板,安装的时候都需要执行一段或几段SQL语句来修改数据结构或者初始化一些数据.大多数ECSHOP管理员为了省事,都会通过 “ECSHOP后台 ...
随机推荐
- Skyline6.5系列覆盖三维地理信息产业上下游
SkylineGlobe将于近日推出6.5 系列产品.该系列产品提供从产业链上游影像处理.中游二三维展示分析.下游具体业务应用等覆盖整个三维空间地理信息产业链的一体化.一站式产品与服务. Skylin ...
- 100+诡异的数据集,20万Eclipse Bug、死囚遗言等
摘要:近日,Robert Seaton整理了100多个最有趣的数据集,其中包括Jeopardy真题,死囚的最后一句话,20万个Eclipse Bug,足球比赛相关,柏拉图式的爱情,太阳系以外的行星,1 ...
- IE6实现图片或背景的圆角效果
使用ie-css3.htc实现背景圆角效果 <!DOCTYPE html> <html> <head> <meta http-equiv="Cont ...
- Ubunbu新建的用户使用SecureCrt无法Table补全、无法高亮
Check 两个地方: 1. 确保/etc/passwd中配置有/bin/bash (这个是用来控制补全). 2. 在~/.bashrc中配置, export TERM=linux (这个是用来控制 ...
- IOC错误
问题描述: The type DbConnection cannot be constructed. You must configure the container to supply this v ...
- 将十六进制的颜色字符串转为UIColor
扩展UIColor,将十六进制的颜色字符串转成UIColor对象. extension UIColor { static func colorWithHexString(hex:String) -&g ...
- UICollectionView瀑布流的实现原理(转)
http://ios.jobbole.com/85689/ 和使用 UIScollView 创刊一个瀑布流是一样的方式 7cc829d3gw1f4nq2oc09zj20j00hvq90.jpg 我的 ...
- Hadoop - 任务调度系统比较
1.概述 在Hadoop应用,随着业务指标的迭代,而使其日趋复杂化的时候,管理Hadoop的相关应用会变成一件头疼的事情,如:作业的依赖调度,任务的运行情况的监控,异常问题的排查等,这些问题会是的我们 ...
- 调用 webapi的put和delete 报"Method Not Allowed" 405 错误。
修改引用到webapi的Dll文件对应的项目的web.config 选择生成读写方法webapi会生成四个读写的方法(CRUD),两个获取数据的.一个更新.一个删除,默认情况下更新和删除是不对外开外的 ...
- win7 VS2012+openCV-2.4.11 配置
1.下载 http://opencv.org/downloads.html (根据版本的不同选择,这里选择的是opencv-2.4.11) 2.安装 3.环境变量配置 计算机->属性->高 ...