资讯详情

SQLServer优化:SQLServer中NOLOCK关键字的用法介绍

7c5ac0350f9d45faba0710978ed1a964.png

1、为什么SQLServer有NOLOCK关键字?

SQLServer未创建查询相当于在不同的查询分析器中创建查询会话。一个典型的例子是,如果您在未正确关闭事务的情况下使用事务插入或操作某个表,其他对数据表的会话查询将被阻塞,因此无法完成查询操作。这个时候有两个解决方案,第一个查询堵塞的对话id然后杀掉会话id,

第二种可以使用WITH(NOLOCK)忽略阻塞的关键字会话直接查询结果。

简单来说NOLOCK关键字的作用是防止查询时被其他会话堵塞,从而顺利完成查询操作。

2、SQLServer有NOLOCK有什么问题

使用NOLOCK关键字可以避免阻塞,导致无法查询数据,但使用该关键字可能会导致数据脏读。以下是一个例子

2.1 创建数据表

CREATE TABLE [dbo].[userInfo] (   [id] varchar(32) COLLATE Chinese_PRC_CI_AS  NOT NULL,   [userName] nvarchar(30) COLLATE Chinese_PRC_CI_AS  NULL,   [birthday] [dbo].[birthday]  NULL,   CONSTRAINT [PK__userInfo__3213E83F0505C75D]    PRIMARY KEY CLUSTERED ([id]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)   ON [PRIMARY] )   ON [PRIMARY] GO INSERT INTO [dbo].[userInfo] ([id], [userName], [birthday])  VALUES ('123', N'小明', '2005-01-02 12:30:00.000'); INSERT INTO [dbo].[userInfo] ([id], [userName], [birthday])  VALUES ('125', N'小孙', '2005-01-02 12:30:00.000');

2.2 创建时候 会话id 为58 开启事务 不关闭事务

begin tran  insert into userInfo (id,userName,birthday) values 2015-01-02 12:30:00.000') --commit tran

2.3 当前会话(58)也可以查询数据

事务尚未提交 此时,数据仍在内存中,未保存在数据库中

select * from userInfo

2.4 新的查询会话 当前新建的id是51

select * from userInfo; select * from userInfo WITH(NOLOCK);

2.5 杀死58会话进程

declare @spid  int  Set @spid  = 58 --表进程 declare @sql varchar(1000) set @sql='kill ' cast(@spid  as varchar) exec(@sql)

3、NOLOCK使用场景

使用频繁操作的表(插入、更新、删除)NOLOCK很合适,但要考虑脏读。

  • 不经常修改的数据表节省了锁定表的时间,大大加快了查询速度。

  • 可以考虑牺牲数据安全性来提高查询效率;

  • 允许脏读的业务逻辑不适合电商、银行等数据完整性要求严格的场景。

  • 当使用NoLock它允许阅读已修改但尚未结束的数据。因此,应考虑transaction不建议使用事务数据的实时完整性。

4、nolock和with(nolock)的区别

三种查询写法

SELECT * FROM A NOLOCK; SELECT * FROM A (NOLOCK); SELECT * FROM A WITH(NOLOCK);

1、SQLServer2005版只支持with(nolock)关键字

2、with(nolock)很容易指定索引

3.不能使用跨数据库服务器查询语句with (nolock) 只能用nolock,查询同一数据服务器时 两者都可以使用

-- SQL Server 建议在2008版之后使用WITH(NOLOCK)写法。

5、表解锁脚本

-- 查询被锁表 select request_session_id   spid ,OBJECT_NAME(resource_associated_entity_id) tableName    from   sys.dm_tran_locks where resource_type='OBJECT'; --参数说明 spid   锁表进程 ;tableName   被锁表名 -- 解锁语句 需要拿到spid然后杀死缩表过程 declare @spid  int  Set @spid  = 57 --锁表进程 declare @sql varchar(1000) set @sql='kill ' cast(@spid  as varchar) exec(@sql)

IT技术共享社区

个人博客网站:https://programmerblog.xyz

文章推荐程序员效率:绘制流程图中常用的工具程序员效率:常用的在线笔记软件远程办公:常用的远程协助软件,你知道吗?51单片机程序下载,ISP串口基础知识硬件:断路器、接触器、继电器基础知识

标签: 3213继电器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台