Sql-Server

在保證不會更改的表上使用 NOLOCK 提示是否完全安全?

  • February 22, 2022
  1. 如果我有一張保證數據永遠不會更改的表,那麼將 NOLOCK 提示添加到針對該表的 SELECT 查詢中是否完全安全?
  2. 如果我有一個表,其中一些行將被更新,但我只選擇保證不會更改的行,這也是使用 NOLOCK 提示的完全安全的場景嗎?

在第一種情況下,我的意思是沒有更新、插入、架構或索引更改。在第二種情況下,相同但僅適用於我要查詢的數據。

如果我有一張保證數據永遠不會更改的表,那麼將 NOLOCK 提示添加到針對該表的 SELECT 查詢中是否完全安全?

在實踐中,是的(儘管沒有這樣記錄),但也無用。如果您的數據永遠不會改變,那麼使用臟讀不會導致任何可觀察到的行為或材料性能差異。

如果我有一個表,其中一些行將被更新,但我只選擇保證不會更改的行,這也是使用 NOLOCK 提示的完全安全的場景嗎?

不,絕對不是。讀取目標行的查詢計劃可能會在沒有適當的並發控制的情況下讀取不斷變化的資料結構。因此,您又希望您的查詢不會返回奇怪、不正確的結果或只是失敗。

在第一種情況下使用 NOLOCK 提示是否有任何(甚至可以忽略不計)性能差異?另外,在第二種情況下,當您說“更改資料結構”時,您是指儲存數據的底層頁面(因為它可以與正在更改的行共享頁面)?

在第一種情況下,如果您不使用 READ COMMITTED SNAPSHOT (由於數據不變而有一些緩解),您可能會看到行鎖定的一些成本。但是在這種情況下使用 TABLOCK 而不是 NOLOCK 將強制為查詢使用單個 S 鎖。TABLOCK 像 NOLOCK 一樣啟用分配順序掃描,但沒有臟讀。

“變化的資料結構”可能包括數據頁和索引。數據頁讀取和索引讀取之間缺乏協調是造成 NOLOCK 錯誤的主要原因。

引用自:https://dba.stackexchange.com/questions/252524