SQL Server數(shù)據(jù)表提示NOLOCK與READPAST
此本文主要介紹了兩種常用的SQL Server數(shù)據(jù)表提示,NOLOCK與READPAST,我前兩天在相關(guān)網(wǎng)站看見SQL Server數(shù)據(jù)表提示,NOLOCK與READPAST的資料,覺得挺好,就拿出來供大家分享。
在其實(shí)際操作中我們主要是建立一個(gè)數(shù)據(jù)表用作例子中查詢數(shù)據(jù)表。執(zhí)行列表A中的腳本建立一個(gè)關(guān)于SalesHistory數(shù)據(jù)表并添加一些數(shù)據(jù)。
NOLOCK
該SQL Server數(shù)據(jù)表提示,也稱為READUNCOMMITTED,只能用于SELECT語句。NOLOCK表明沒有對(duì)數(shù)據(jù)表添加共享鎖以阻止其它事務(wù)對(duì)數(shù)據(jù)表數(shù)據(jù)的修改。
該語句的好處是它可以使數(shù)據(jù)庫引擎不用在處理查詢中的上鎖問題,可以提高并發(fā)性并改善數(shù)據(jù)庫性能,因?yàn)閿?shù)據(jù)庫引擎不用在維護(hù)共享鎖的使用問題。存在的問題是因?yàn)樵撜Z句不能處理要讀取的數(shù)據(jù)表的所有鎖,所以一些“臟數(shù)據(jù)”或未被提交的數(shù)據(jù)潛在的可能被讀取。
如果某個(gè)事務(wù)被滾回,那么應(yīng)用了NOLOCK連接的數(shù)據(jù)讀取操作將可以讀取未提交的數(shù)據(jù)。這種類型的讀取導(dǎo)致處理的不一致性會(huì)帶來很多問題。這是你使用NOLOCK時(shí)應(yīng)該了解的技巧。
作為一個(gè)負(fù)面影響,NOLOCK查詢還可能帶來讀取“幻影”數(shù)據(jù)或讀取在一個(gè)數(shù)據(jù)庫讀取事務(wù)中可以獲得的但在另一個(gè)事務(wù)中可能被滾回的數(shù)據(jù)的風(fēng)險(xiǎn)。(我將在本系列文章的第二部分對(duì)這個(gè)負(fù)面影響進(jìn)行詳細(xì)說明。)
下面的例子展示了NOLOCK如何工作以及臟數(shù)據(jù)讀取是如何產(chǎn)生的。在下面的腳本中,我用一個(gè)事務(wù)在SalesHistory數(shù)據(jù)表中插入一條記錄。
- BEGIN TRANSACTION
- INSERT INTO SalesHistory
- (Product, SaleDate, SalePrice)
- VALUES
- ('PoolTable', GETDATE(), 500)
這個(gè)事務(wù)仍舊是開放的,這意味著仍可以對(duì)插入數(shù)據(jù)表的記錄上鎖以阻止其它操作。在一個(gè)新的查詢窗口中,運(yùn)行下面的腳本,該腳本使用NOLOCKSQL Server數(shù)據(jù)表提示返回SalesHistory數(shù)據(jù)表中的記錄數(shù)。
- SELECT COUNT(*) FROM SalesHistory WITH(NOLOCK)
返回記錄數(shù)值為301。因?yàn)閷?duì)SalesHistory數(shù)據(jù)表插入記錄的事務(wù)還沒有提交,所以我們可以撤銷它。我通過使用下面的語句將事務(wù)滾回:
- ROLLBACK TRANSACTION
該語句從SalesHistory數(shù)據(jù)表中刪除前面插入的記錄?,F(xiàn)在我們運(yùn)行前面運(yùn)行的同樣的SELECT語句。
- SELECT COUNT(*) FROM SalesHistory WITH(NOLOCK)
這次返回記錄數(shù)的值為300。我***次查詢讀記錄的事務(wù)還沒有提交,這就是一個(gè)臟數(shù)據(jù)讀取。
- READPAST
這是一個(gè)比NOLOCK較少使用的數(shù)據(jù)表提示。這個(gè)提示指明數(shù)據(jù)庫引擎返回結(jié)果時(shí)忽略加鎖的行或數(shù)據(jù)頁。
這個(gè)數(shù)據(jù)表提示的優(yōu)點(diǎn)和NOLOCK一樣,在處理查詢時(shí)不會(huì)發(fā)生阻塞。此外,讀臟數(shù)據(jù)并不會(huì)出現(xiàn)在READPASTA中,因?yàn)椴粫?huì)返回鎖定的記錄。這個(gè)語句的缺點(diǎn)是,因?yàn)椴环祷劓i定的記錄,所以很難確定結(jié)果集或修改語句是否包含所有必須的記錄。在你的應(yīng)用中可能需要添加一些邏輯來確保最終包含所有必須的記錄。
READPAST數(shù)據(jù)表提示的例子和NOLOCK的例子類似。我將使用一個(gè)事務(wù)來更新SalesHistory數(shù)據(jù)表中的一個(gè)記錄。
- BEGIN TRANSACTION
- UPDATE ***) SalesHistory
- SET SalePriceSalePrice = SalePrice + 1
因?yàn)槲覜]有提交或回滾這個(gè)事務(wù),所以添加在更新記錄上的鎖仍舊有效。在一個(gè)新的查詢編輯窗口中,運(yùn)行下面的腳本,該腳本對(duì)SalesHistory數(shù)據(jù)表使用READPAST統(tǒng)計(jì)表中的記錄數(shù)。
- SELECT COUNT(*)
- FROM SalesHistory WITH(READPAST)
最初SalesHistory數(shù)據(jù)表中包含300條記錄,UPDATE語句正鎖定表中一條記錄,所以上面使用READPAST的腳本返回結(jié)果為299條記錄,這說明我要更新的記錄被鎖定,所以被REASPAST提示忽略。
以上的相關(guān)內(nèi)容就是介紹兩種SQL Server數(shù)據(jù)表提示的介紹,望你能有所收獲。
【編輯推薦】
- SQL Server視圖運(yùn)行的提高與索引
- SQL Server數(shù)據(jù)庫修復(fù)用SQL語句,很簡(jiǎn)單!
- SQL Server性能進(jìn)行提高的4項(xiàng)技術(shù)概述
- SQL Server使用convert對(duì)datetime日期數(shù)據(jù)進(jìn)行獲取
- SQL Server數(shù)據(jù)轉(zhuǎn)換服務(wù)的妙招之一