SQLServer的with(nolock)用法


1. with(nolock)介紹

nolock 是 SQLServer 特有的功能。

例如:對於一個表 A,更新了一行,還沒有commit,這時再select * from A 就會死鎖。

用select * from A(nolock)可以防止死鎖,nolock可以忽略鎖,直接從數據庫讀取數據。這意味着可以避開鎖,從而提高性能和擴展性。

但同時也意味着代碼出錯的可能性存在。你可能會讀取到運行事務正在處理的無須驗證的未遞交數據。 這種風險可以量化。

mysql 沒有這方面問題,對於一個表 A,更新了一行,還沒有commit, select * from A, 將查詢到更新以前的原始數據記錄,而不會出現死鎖問題。

要提升SQL的查詢效能,首先會想到建立索引(index),或者會在表后面加一個nolock,或者是with(nolock),其目的就是查詢是不鎖定表,從而達到提高查詢速度的目的。

當同一時間有多個用戶訪問同一資源,並發用戶中如果有用戶對資源做了修改,此時就會對其它用戶產生某些不利的影響,例如:

1、臟讀

一個用戶對一個資源做了修改,此時另外一個用戶正好讀取了這條被修改的記錄,然后,第一個用戶放棄修改,數據回到修改之前,這兩個不同的結果就是臟讀。

2、不可重復讀

一個用戶的一個操作是一個事務,這個事務分兩次讀取同一條記錄,如果第一次讀取后,有另外用戶修改了這個數據,然后第二次讀取的數據正好是其它用戶修改的數據,這樣造成兩次讀取的記錄不同,如果事務中鎖定這條記錄就可以避免。

3、幻讀

指用戶讀取一批記錄的情況,用戶兩次查詢同一條件的一批記錄,第一次查詢后,有其它用戶對這批數據做了修改,方法可能是修改,刪除,新增,第二次查詢時,會發現第一次查詢的記錄條目有的不在第二次查詢結果中,或者是第二次查詢的條目不在第一次查詢的內容中。

NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等於 READ UNCOMMITTED事務隔離級別 。

nolock確實在查詢時能提高速度,但它並不是沒有缺點的,起碼它會引起臟讀、只適用與select查詢語句。 

在一些不需要考慮臟讀的場合會用到,例如當用戶在論壇發廣告貼時刪除其所有發帖,這個查詢就不怕臟讀,全刪,或者漏一個正在發的都不是問題。

2. 使用方式(SqlServer)

SELECT * FROM [dbo].[user] WITH (NOLOCK) WHERE id = 1

3. with(nolock)的使用場景

1、數據量特別大的表,犧牲數據安全性來提升性能是可以考慮的;

2、允許出現臟讀現象的業務邏輯,反之一些數據完整性要求比較嚴格的場景就不合適了,像金融方面等。

3、數據不經常修改的表,這樣會省於鎖定表的時間來大大加快查詢速度。

4、當使用NoLock時,它允許閱讀那些已經修改但是還沒有交易完成的數據。因此如果有需要考慮transaction事務數據的實時完整性時,使用WITH (NOLOCK)就要好好考慮一下。

4. nolock和with(nolock)的區別

1、SQL05中的同義詞,只支持with(nolock)。

2、with(nolock)的寫法非常容易再指定索引。

3、跨服務器查詢語句時 不能用with (nolock) 只能用nolock,同一個服務器查詢時 則with(nolock)和nolock都可以用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM