數據庫優化:SqlServer的with(nolock)關鍵字的用法介紹

一、with(nolock)的介紹

數據庫寫查詢語句的時候,為了提升查詢性能,往往會在查詢的表后面加一個nolock,或者是with(nolock),其目的就是查詢的時候是不鎖定表,從而提高查詢速度的目的。但如果同一時間有多個用戶訪問同一資源的時候,如果并發用戶對該資源做了修改。則會對其他用戶訪問該數據造成數據不一致的情況。主要

體現下面三種情況。

1、臟讀

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

2、不可重復讀

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

3、幻讀

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

NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等于 READ UNCOMMITTED事務隔離級別 。nolock確實在查詢時能提高速度,但它并不是沒有缺點的,起碼它會引起臟讀、只適用于select查詢語句。在一些不需要考慮臟讀的場合會用到,例如當用戶在論壇發廣告貼時刪除其所有發帖,這個查詢就不怕臟讀,全刪,或者漏一個正在發的都不是問題。

二、舉個例子

下面就來演示這個情況。

為了演示兩個事務死鎖的情況,我們下面的測試都需要在SQL Server Management Studio中打開兩個查詢窗口。保證事務不被干擾。?

1、 沒有提交的事務,NOLOCK 和 READPAST處理的策略:

查詢窗口一請執行如下腳本:

CREATE TABLE t1 (c1 int IDENTITY(1,1), c2 int)

go

BEGIN TRANSACTION

insert t1(c2) values(1)?

2、在查詢窗口一執行后,查詢窗口二執行如下腳本:

select count(*) from t1 WITH(NOLOCK)

select count(*) from t1 WITH(READPAST)?

結果與分析:

查詢窗口二依次顯示統計結果為:1、0

查詢窗口一的命令沒有提交事務,所以 READPAST 不會計算沒有提交事務的這一條記錄,這一條被鎖住了,READPAST 看不到;而NOLOCK則可以看到被鎖住的這一條記錄。?

如果這時候我們在查詢窗口二中執行:

select count(*) from t1 就會看到這個執行很久不能執行完畢,因為這個查詢遇到了一個死鎖。

清除掉這個測試環境,需要在查詢窗口一中再執行如下語句:

ROLLBACK TRANSACTION

drop table t1

演示二:對被鎖住的記錄,NOLOCK 和 READPAST處理的策略

這個演示同樣需要兩個查詢窗口。

請在查詢窗口一中執行如下語句:

CREATE TABLE t2 (UserID int , NickName nvarchar(50))

go

insert t2(UserID,NickName) values(1,'lucas')

insert t2(UserID,NickName) values(2,'fuckcpp')

go

BEGIN TRANSACTION

update t2 set NickName = 'fuckcpp.net' where UserID = 2?

請在查詢窗口二中執行如下腳本:

select * from t2 WITH(NOLOCK) where UserID = 2

select * from t2 WITH(READPAST) where UserID = 2

結果與分析:

查詢窗口二中, NOLOCK 對應的查詢結果中我們看到了修改后的記錄,READPAST對應的查詢結果中我們沒有看到任何一條記錄。這種情況下就可能發生臟讀

三、with(nolock)的適用場景

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

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

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

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

IT技術分享社區

文章推薦程序員效率:畫流程圖常用的工具程序員效率:整理常用的在線筆記軟件遠程辦公:常用的遠程協助軟件,你都知道嗎?51單片機程序下載、ISP及串口基礎知識硬件:斷路器、接觸器、繼電器基礎知識

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271708.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271708.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271708.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

對layoutInflater的理解

參考該博客:http://www.cnblogs.com/top5/archive/2012/05/04/2482328.html LayoutInflater是一個抽象類,通過調用其實例方法inflate(),將res/layout下的xml布局文件進行實例化,不同于findvirebyid()是找布局文件下的控件進行實例…

linux /root /etc,Linux知識:/root/.bashrc與/etc/profile的異同

要搞清bashrc與profile的區別,首先要弄明白什么是交互式shell和非交互式shell,什么是login shell 和non-login shell。交互式模式就是shell等待你的輸入,并且執行你提交的命令。這種模式被稱作交互式是因為shell與用戶進行交互。這種模式也是…

java多線程售票例子

代碼如下: public class Ticket1 implements Runnable {private int tickets 100;Overridepublic void run() {while (tickets > 0) {synchronized (Ticket.class) {if (tickets > 0) {tickets--;System.out.println(Thread.currentThread().getName() "正在賣票&…

推薦一款免費國產遠程辦公神器ToDesk,TeamViewer完美替代品

對于從事IT行業的人員來說,遠程軟件基本上是必備的軟件。之前使用用TeamViewer遠程辦公軟件,它的穩定性、延遲低、功能齊全很受廣大開發者的歡迎。唯一美中不足的是它是一款商業軟件。費用比較高。到現在基本上所有破解工具都無效了。所以不得不放棄這款…

[iOS] photoKit獲取所有照片

代碼: - (NSMutableArray *)getAllPhoto{NSMutableArray *arr [NSMutableArray array];// 所有智能相冊PHFetchResult *smartAlbums [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular optio…

用python寫linux中的ls,Python實現Linux環境下的ls命令

在Linux下使用ls命令結合正則表達式,能夠高效地進行文件搜索,并通過參數操作文件,于是就想用Python實現這個功能以便在Windows上使用import osimport reimport syspath os.getcwd()substr raw_input(The sub-string of the file (Support f…

蘋果臺式電腦怎么開機_龍華蘋果電腦回收公司,臺式電腦回收公司電話

龍華蘋果電腦回收公司,臺式電腦回收公司電話oDYIHx 通常液晶顯示器有VGA和DVI兩種種接口,其中VGA接口在長時間顯示后悔出現畫面模糊情況,需要校正才能恢復,然而DVi接口傳輸就比較穩定,它屬于全數字無損傳輸信號,在長…

AtomicInteger使用非阻塞算法,實現并發控制多線程實現售票

代碼如下: public class TicketDemo implements Runnable {private static volatile AtomicInteger ticketSum new AtomicInteger(20);private static int finalTotal 0;Overridepublic void run() {int count;while ((count ticketSum.decrementAndGet()) > 0) {System.…

數據庫:SQLServer 實現行轉列、列轉行用法筆記

在許多的互聯網項目當中,報表開發是整個項目當中很重要的一個功能模塊。其中會有一些比較復雜的報表統計需要行轉列或者列轉行的需求。今天給大家簡單介紹一下在SQLServer當中如何使用PIVOT、UNPIVOT內置函數實現數據報表的行轉列、列轉行。有需要的朋友可以一起學習…

硬件知識:串口通訊的起始、數據、停止位是怎么分配的?

串口是串行接口(serial port)的簡稱,也稱為串行通信接口或COM接口。串口通信是指采用串行通信協議(serial communication)在一條信號線上將數據一個比特一個比特地逐位進行傳輸的通信模式。串口按電氣標準及協議來劃分…

ES5 getter setter

最近在學習vuejs,了解到內部實現使用到了es5的Getters和Setters。之前看高程的時候,沒有重視這塊,今天查看一下文檔,了解了他們的作用,再次記錄一下,可供以后查看和共享。 定義Getters和Setters&#xff1a…

python 調用bat失敗_要想順利通過Python面試,你最起碼需要達到白銀段位!

近幾年 Python 非常熱門,在學術界和產業界的使用率顯著提高。目前學習Python的人數日益增多,Python在近3年的編程語言受歡迎度中一直處于榜首。今天我們就來講講在產業界,需要具備哪些能力才能獲得一個滿意的 Python 相關崗位 Offer。Python基…

多線程售票demo,用ReentrantLock實現

代碼: public class TicketReentLockDemo implements Runnable {private int ticketTotal 100;private Lock lock new ReentrantLock();Overridepublic void run() {while (ticketTotal > 0) {try {lock.lock();if (ticketTotal > 0) {try {TimeUnit.MILLISECONDS.sle…

在linux安裝不了apache,Apache 不能安裝在linux?

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓官網下載了tar.gz的文件, 然后tar解壓, 可是走到 ./configureprefix/usr/local/apache/ 的時候就開始出現一些“NO”我怕這樣make會有問題, 請問大家碰到出現"no"的選項嘛?…

andriod sqlite 詳解轉載

SQLite簡介 Google為Andriod的較大的數據處理提供了SQLite,他在數據存儲、管理、維護等各方面都相當出色,功能也非常的強大。SQLite具備下列特點: 1.輕量級 使用 SQLite 只需要帶一個動態庫,就可以享受它的全部功能,而…

數據庫:SQLServer中in和 exists函數用法筆記

今天給大家分享一下SQLServer中in和 exists 用法,希望能對大家有所幫助。一、IN 用法確定指定的值是否與子查詢或列表中的數據相匹配。1.1 語法格式test_expression [ NOT ] IN ( subquery | expression [ ,...n ] )1.2 參數說明test_expression為任意有…

什么是m叉樹_不懂數據庫索引的底層原理?那是因為你心里沒點b樹

前幾天下班回到家后正在處理一個白天沒解決的bug,廁所突然傳來對象的聲音: 對象:xx,你有《時間簡史》嗎? 我:我去!妹子,你這啥癖好啊,我有時間也不會去撿屎啊&#xff01…

可重入鎖是什么和demo

可重入鎖 reentrantlock是獨占鎖且可重入的 synchronized 也可以重入 可重入意思就是這個線程已經獲取鎖了,你再獲取該鎖還能獲取 獲取的還是原來的鎖 不會出現問題 可以降低編程難度 代碼如下: new Thread(new Runnable() {Overridepublic void run() {synchr…

linux 安裝python 3.x,Linux 安裝python3.x步驟

本文轉發自博客園非真的文章,內容略有改動linux系統本身默認安裝有2.x版本的python,版本x根據不同版本系統有所不同,通過python --V 或 python --version 查看系統自帶的python版本。有一些系統命令時需要用到python2,不能卸載&am…

數據庫:SQLServer中游標的用法筆記

一、游標的概念知識游標可以理解為SQL Server的一種數據訪問機制,它允許用戶訪問數據的維度是數據行。用戶可以對每一行數據進行單獨處理,從而降低系統開銷和潛在的阻隔情況,游標主要用于存儲過程,觸發器和 T_SQL復雜的腳本中&…