SQL Server优化:SQL Server中Nolock关键字的用法

网友投稿 959 2023-06-05

***优化:***中Nolock关键字的用法

***优化:***中Nolock关键字的用法

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

***没创建一个查询,都相当于创建一个查询会话,在不同的查询分析器里面进行的查询操作,可能会影响别的查询会话。比较典型的一个例子,如果你正在使用事务执行某一张表的插入或者操作而没有正确关闭事务的情况下,会造成别的会话针对该数据表的查询都会处于阻塞的状态,从而不能完成查询的操作。这个时候有两个解决方案,第一种查询到阻塞的会话id然后杀掉该会话id,第二种可以使用WITH(NOLOCK)关键字忽略掉阻塞的会话直接查询出结果。

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

2、***有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 开启事务 不关闭事务

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);

*** 2005版本中,只支持with(nolock)关键字with(nolock)的写法非常容易再指定索引跨数据库服务器查询语句时不能用with (nolock) 只能用nolock,同数据服务器查询时 两者都可以用-- *** 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)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:金融数据架构设计观,数字金融时代央行数据架构分析
下一篇:亚马逊云科技 INNOVATE | 数据驱动创新在线大会耀目来袭!
相关文章