鎖公升級與執行計畫情況

2021-09-07 06:03:11 字數 1874 閱讀 7082

鎖公升級(lock escalations)非常非常不好,因為最後你會是在表級別有排它或共享鎖。在表級別放上這樣的限制鎖會降低你的併發和資料庫的吞吐量。

今天我不想討論鎖公升級的基本資訊,今天我想詳細談下當鎖公升級觸發時,sql server的這種鎖行為對執行計畫情況的影響。

假設我們有如下非常簡單的查詢:

1

select

*from

sales.salesorderdetail

2where modifieddate >

'20200501'3

go

如你所見,我就從sales.salesorderdetail表請求modifieddate晚於2023年5月1日的記錄。當然,這個查詢不會返回任何記錄,因為選擇的日期是將來的。

但當你檢視執行計畫時,你會看到查詢優化器選擇了完整的聚集索引掃瞄運算子,緊接著是篩選運算子。

在執行計畫裡,乙個完整的聚集索引掃瞄運算子,緊接著是乙個篩選器運算子真的是乙個不好的模式。它意味著一開始(在掃瞄運算子),你就讀取大量的資料,接下來(在篩選器運算子)你剔除不符合的資料。物理上你讀取的記錄數比你邏輯請求的數多很多。在這個例子裡,我從sales.salesorderdetail表讀取了121317條記錄,但沒有1條記錄符合我的查詢謂語(基於modifieddate列)。因此所有列在篩選器運算子被剔除。

現在假設你在像可重複讀(repeatable read)這樣更多限制的事務隔離級別執行這個查詢。在這個情況下,sql server必須把持共享鎖直到事務結束。也就是說,當你讀取超過5000條記錄時,在聚集索引掃瞄期間,sql server會觸發鎖公升級。這會很糟糕,因為事後讀取的不符合的資料會在篩選器剔除。你啥也沒做就觸發了鎖公升級。

你必須接受篩選器運算子非常不好。但我們可以做的更好麼?當然,因為sql server也支援所謂的剩餘謂語(residual predicate):當記錄從資料頁讀取時,這個謂語會「直接」在儲存引擎內部評估。當謂語滿足時,行是在儲存引擎外傳入執行計畫。如果謂語不滿足,行會忽略並消失。在執行計畫裡,它不會移交給下個運算子。

這個和篩選器運算子完全不同!使用剩餘謂語,你只處理在執行計畫裡邏輯請求的行(你還是要讀取請求的資料頁……)。當基於剩餘謂語沒有符合的行時,沒有行在執行計畫裡運輸。我們來看下面的查詢。

1

select

*from person.person with (index(1))2

where modifieddate >

'20200501'3

go

這裡我從person.person表請求行,同樣對於選擇的查詢謂語沒有行返回。但這次sql server能把查詢謂語以剩餘謂語的方式壓入儲存引擎。因此查詢謂語在儲存引擎裡直接評估:

當你在可重複讀(repeatable read)事務隔離級別裡執行這個查詢時,你不會再觸發鎖公升級,因為在執行計畫裡你不處理任何行——在儲存引擎裡它們就被或略了。因此對於查詢,你是否會觸發鎖公升級取決與你的執行計畫情況……

如你在這篇文章裡所見,執行計畫情況會大大影響sql server的鎖行為。剩餘謂語就像帥選器運算子,但它是在儲存引擎裡,從資料頁讀取行後,直接評估。它是sql server僱傭的效能優化者。

在一些情況下,查詢優化器可以把查詢謂語作為剩餘謂語壓入儲存引擎,但在一些情況下做不到,查詢優化器只能引入篩選器運算子。不要問我什麼情況是可以的,什麼情況是不可以的。這個行為微軟也沒有文件說明……

感謝關注!

搬家計畫執行情況

今天一整天都在打包,書已經搞定了,亂七八糟的零碎也收拾了好多。老爸擔心我整理打包比較累,不過我這個人不太能吃苦,所以想了個辦法,我把電腦開啟,打算邊看節目邊整理,應該也蠻有意思的。不過,很快我就發現看電影電視都不方便,想想阿,收拾東西的時候沒有多少時間可以盯著電腦螢幕,可是不看螢幕是很影響看節目的。...

synchronized與鎖公升級

當乙個共享資源有可能被多個執行緒同時訪問並修改的時候,需要用鎖來保證資料的正確性。請看下圖 執行緒a和執行緒b分別往同乙個銀行賬戶裡面新增貨幣,a執行緒從記憶體中讀取 read 當前賬戶金額 0 到執行緒a的本地棧,進行 100的操作後,這時b執行緒也從記憶體中讀取當前金額 0 到執行緒b的本地棧,...

計畫與執行力回顧

10年toastmasters 經歷,2007年11月份加入,到2017年1月份獲得最高教育成長獎勵 dtm distinguished toastmaster toastmasters 清晰的成長路徑規劃讓人一目了然。剩下的就是怎麼堅持到底了。乘俱樂部10周年慶典 2017 12 13 之際,我對...