2012-02-27 95 views
2

在我的SQL tempOrder表中有數百萬條記錄並且有10個觸發器用於更新tempOrder表與另一個表的更新。在SQL Server 2008中使用表(NOLOCK)

所以我想申請with(NOLOCK)在桌子上。

我知道有

SELECT * FROM temporder with(NOLOCK)

這種說法我能做到。但有什麼辦法可以將with(NOLOCK)直接應用到SQL Server 2008的表中。

+0

你是問,如果你可以做一些表格,使得一些鎖類型從來沒有得到? – rjdevereux 2012-02-27 11:44:44

+6

爲什麼近來人們用槍射擊他們的腳不開心?至少他們要求一個火箭筒。 – GSerg 2012-02-27 11:48:56

+0

@GSerg我同意,但很難說出經驗豐富的人是如何。有時候人們知道風險,有時他們認爲他們已經找到了減緩查詢速度的靈丹妙藥。 – 2012-02-27 12:30:09

回答

7

你的問題的直接答案是否 - 沒有選擇告訴SQL 從不鎖定表X。就這樣說,你的問題打開了一系列應該提出的事情。

隔離級別

首先,最直接的方式,你可以完成你想要的是使用with (nolock)選項或SET TRANSACTION ISLOATION LEVEL READ UNCOMMITTED(又名混亂)。這些選項分別適用於查詢或連接的持續時間。如果我選擇這條路線,我會將它與長時間運行的SQL事件探查器跟蹤結合起來,以確定在TableX上鎖定任何查詢。

鎖升級

其次,SQL服務器確實有一個表寬LOCK_ESCALATION閾值(如ALTER TABLE SET LOCK_ESCALATION x執行,其中X是鎖或AUTO的數量)。這可以控制SQL何時嘗試將許多細粒度的鎖合併成更少的粗粒鎖。換句話說,它是一個數字閾值,用於轉換在單個數據庫對象(think索引)上取出多少個鎖。

重寫SQL的鎖定通常不是一個好主意。由於documentation states

在大多數情況下,數據庫引擎時 和用於鎖定和鎖升級其默認設置運行提供最佳性能。

由於直覺,因爲它看起來,從你描述你的情況可能有一些運氣用更少的廣闊鎖而不是NOLOCK。你需要用實際工作負載來測試這個理論,以確定它是否值得。

快照隔離

您可能還檢查出SNAPSHOT隔離級別。您的問題中沒有足夠的信息可以知道,但我懷疑這會有所幫助。 NOLOCK的

危險

雖這麼說,你可能已經從@ GSerg的評論回升,NOLOCK可以避邪。 No-Lock通俗地稱爲混沌 - 並有充分的理由。當開發者首次遇到NOLOCK時,似乎允許髒讀是唯一的含義。還有更多......

  • 髒數據被讀取不一致的結果(共同印象)
  • 錯誤數據 - 這意味着無論你的數據的預寫或寫後的狀態保持一致。
  • 硬例外(如錯誤601,由於數據移動)終止您的查詢返回
  • 空白數據
  • 先前提交的行被錯過
  • 畸形字節返回

但是不要拿我的話:

+0

有禮貌! – 2012-03-26 20:33:34

2

您不能更改表或數據庫的默認隔離級別(快照除外),但是您可以更改它的所有讀取查詢一個交易:

set transaction isolation level read uncommitted

更多信息請參見msdn

2

這不是表的配置。

如果您將(nolock)添加到查詢中(稱爲查詢提示),則表示在執行此查詢(並且僅執行此操作)時,它不會在受影響的表上創建鎖定。

當然,通過將事務隔離級別設置爲未提交讀取,例如:set transaction isolation level read uncommitted,可以使此配置對於當前連接是永久的。但是,只有在連接打開之前它纔有效。

也許如果你更詳細地解釋你想達到的目標,我們可以更好地幫助你。

+0

感謝您的回覆。這有助於我 – 2012-02-27 12:24:11