SQL Server 2008 R2 - ReadCommitted隔離級別更新到獨佔鎖轉換
我試圖準確確定SQL服務器何時將更新鎖轉換爲獨佔鎖。例如,我有表dbo.TableA。 dbo.TableA有兩個列PKCol1和NCCol2。 PKCol1是一個聚集索引,NCCol2上有一個非聚集索引。如果我是執行
BEGIN TRAN
DELETE
FROM dbo.TableA
WHERE NCCol2 = 1
COMMIT TRANSACTION
而優化器選擇掃描NCCol2找到所有候選記錄,將在非聚集索引操作掃描索引中的所有記錄。在聚簇索引刪除操作員將這些鎖轉換爲排他鎖並刪除之前,將更新鎖添加到每個候選記錄,直到它掃描完整個索引。
或者非聚集索引運算符是否會掃描每條記錄,然後將更新鎖添加到候選記錄,評估該行是否匹配,以及是否將更新鎖轉換爲排它鎖。
基本上哪個運算符將更新鎖轉換爲排他鎖,非聚集索引掃描一旦掃描發現該記錄是匹配或聚集索引刪除候選行一旦識別並傳遞給它?
聯機叢書告訴我
更新(U)
用於可更新的資源。防止當多個會話在讀取,鎖定和以後可能更新資源
和
專屬
用於數據修改操作,例如INSERT(X),更新發生死鎖的常見形式或DELETE。確保不能同時對同一資源進行多個更新。
其他信息1
我其實是調查其對非唯一的非聚集INT索引2發生以下後優化器選擇了以下計劃
僵局譯爲
死鎖- 受害者對dbo表進行更新鎖定。表1索引2行1
- 業主承擔了dbo.Table1索引2的排它鎖ROW2
- 受害者等待上dbo.Table1索引2更新鎖ROW2
- 所有者等待上dbo.Table1索引2更新鎖ROW1
這是我的理解是,執行計劃中的每個操作符都是按照從右到左的順序完整執行的。但我的理解是,更新鎖只在UPDATE/INSERT或DELETE期間轉換爲排它鎖,即聚簇索引刪除操作符。因此,我不確定爲什麼步驟2中的所有者對Index2 row2有獨佔鎖定,這表明它處於聚簇索引刪除步驟,但仍在等待更新鎖定,這將表明它也是非聚簇索引掃描步驟。它怎麼可能在同一時間的兩個步驟?
但是,如果你認爲這兩個更新和排它鎖索引過程中取得的掃描然後這個僵局會更有意義。
經過重新編譯優化器選擇上尋求聚集索引,沒有任何問題
@Bogdan Sahlean & @布賴恩 - 非常感謝您的幫助和建議。
+1爲內部@博格丹。只要NCCol2與其相比較的相等值相同,這種情況就會成立。例如,如果NCCol2是varchar(25)並且相等值爲int,則它將作爲nc掃描,因爲數據類型優先級要求varchar端在比較之前隱式轉換爲int。如果你沒有考慮到這一點,你顯然會比我更聰明的開發者工作。 – brian
@brian:謝謝。我同意,但將隱含/顯式轉換的信息添加到我的答案中並非我的意圖。 Jonathan Kehayias在這個問題上有非常好的博客文章:[鏈接](http://www.sqlskills.com/blogs/jonathan/implicit-conversions-that-cause-index-scans/)。 –
再次+1。同意,但OP選擇掃描直接跳入優化器。這導致我想知道他/她在試圖理解的問題中是否沒有數據類型不匹配。無論是NCCol2 = 1還是非常低的選擇性,並且掃描比尋找便宜。不要誤解我的意思,你無法更好地解釋鎖升級。 – brian