首页 > 数据库 >SQL 中为什么经常要加NOLOCK?

SQL 中为什么经常要加NOLOCK?

时间:2023-07-05 15:57:25浏览次数:41  
标签:要加 查询 会话 NOLOCK SQL 我们 SELECT

刚开始工作的时候,经常听同事说在SQL代码的表后面加上WITH(NOLOCK)会好一些,后来仔细研究测试了一下,终于知道为什么了。

那么加与不加到底有什么区别呢?

SQL在每次新建一个查询,就相当于创建了一个会话。在不同的查询窗口操作,会影响到其他会话的查询。当某张表正在写数据时,这时候去查询很可能就会一直处于阻塞状态,哪怕你只是一个很简单的SELECT也会一直等待。

我们这里使用事务来往某张表里写数据,我们知道事务在写完表必须提交(COMMIT)或回滚(ROLLBACK)才能释放表,否则会一直处于阻塞状态。

在插入过程中,我们写一个简单的查询语句,在不添加WITH(NOLOCK)和添加WITH(NOLOCK)的情况下,看会发生什么。

 

示例数据

如下表A,是我们新建的一个非常简单的表。

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

我们发现有1行受影响了,注意这里的会话ID是59(左上角黄色标签上的数字)

 

不添加NOLOCK

我们新建一个查询窗口,然后查询A表

从上面的查询可以看到,表A被锁住了,我们的查询一直处于阻塞状态。这里的会话ID是60

这个时候如果你在会话59的窗口执行COMMIT或ROLLBACK,会话60的查询结果会立刻显示出来,这里为了下面的演示我们暂时不提交或回滚。

 

添加NOLOCK

我们再新建一个查询窗口,还是查询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)

标签:要加,查询,会话,NOLOCK,SQL,我们,SELECT
From: https://www.cnblogs.com/cw2022/p/17528741.html

相关文章

  • MySQL数据库8.0.29-8.0.31版本使用 INSTANT 算法新增字段bug
    xxx下发MySQL数据库共性隐患排查通知,要求统一排查MySQL数据库8.0.29及以后版本使用INSTANT算法新增字段后期变更回滚可能导致数据库宕机的隐患,排查方法及整改方法详见下表和附件。请各分支()数据库运营人员集中排查隐患,及时整改。 隐患概述MySQL数据库8.0.29及以后版本......
  • MySQL常用字符串函数
    一、常用函数1.1ASCII(str)返回值为字符串str的最左字符的数值,即取得最左字符的ascii码。假如str为空字符串,则返回值为0。假如str为null,则返回值为null。mysql>selectascii('a');+--------------+|ascii('a')|+--------------+|97|+--------------+1rowin......
  • MySQL:SQL 错误 [1118] [42000]: Row size too large.
    1.场景:今天在用MySQL建表的时候,报了一个错误;SQL错误[1118][42000]:Rowsizetoolarge.Themaximumrowsizefortheusedtabletype,notcountingBLOBs,is65535.Thisincludesstorageoverhead,checkthemanual.YouhavetochangesomecolumnstoTEXTorBL......
  • sqlsugar 使用汇总 (大数据写入、更新,大数据更新 ORM, db.Fastest文档)
     https://www.donet5.com/Home/Doc?typeId=2404  大数据写入、更新,大数据更新ORM,db.Fastest文档//插入100万10秒不到db.Fastest<RealmAuctionDatum>().BulkCopy(GetList());//性能比现有任何Bulkcopy都要快30%//如果数据库现有数据比较多出现比较慢,这个时候可以试试......
  • Mysql进阶篇(一)之存储引擎
    一.MySQL体系结构1.连接层最上层是一些客户端和链接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可......
  • MySQL-锁等待排查
    背景最近我们的登录系统在每个钟点的18分就会登录不进去,排查后发现有锁等待情况,周期地发生那么很大几率是自动任务了,为了找到为什么会锁等待,我们做了以下的排查排查过程--1.锁住的事务SELECT*FROMINFORMATION_SCHEMA.INNODB_LOCKS;--2.事务SELECT*FROMIN......
  • mssql执行大文件 还原数据库
     解决脚本还原数据库文件过大,打开卡顿问题1、打开MSSQL安装路径:找到MicrosoftSQLServerManagementStudio的图标,点击右键属性>打开文件位置2、在安装路径下打开cmd控制台3、输入命令:C:\ProgramFiles(x86)\MicrosoftSQLServerManagementStudio18\Common7\IDE>sqlcm......
  • PostgreSQL 管理数据表(二)
    修改表当我们创建好一个表之后,可能会由于业务变更或者其他原因需要修改它的结构。PostgreSQL使ALTERTABLE语句修改表的定义:ALTERTABLEnameaction;其中的action表示要执行的操作。常见的修改操作包括:添加字段删除字段添加约束删除约束修改字段默认值修改字段数据类......
  • PostgreSQL 管理数据表(一)
    创建表在PostgreSQL中,使用CREATETABLE语句创建一个新表:CREATETABLEtable_name(column_namedata_typecolumn_constraint,column_namedata_type,...,table_constraint);建表语句说明首先,table_name指定了新表的名称。括号内是字段的定义,column......
  • PostgreSQL 管理数据表(三)
    删除约束删除约束通常需要知道它的名称,可以通过psql工具的\dtable_name命令查看表的约束。ALTERTABLEtable_nameDROPCONSTRAINTconstraint_name[RESTRICT|CASCADE];RESTRICT是默认值,如果存在其他依赖于该约束的对象,需要使用CASCADE执行级联删除。例如,外键约束依赖......