SQLServer优化:SQLServer中NOLOCK关键字的用法介绍
? ? ??? ? ? ? ?
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 ('127','小張','2015-01-02 12:30:00.000') --commit tran2.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及串口基礎知識硬件:斷路器、接觸器、繼電器基礎知識
總結
以上是生活随笔為你收集整理的SQLServer优化:SQLServer中NOLOCK关键字的用法介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tomcat常用功能
- 下一篇: Linux:程序员必备的21条Linux