簡體   English   中英

SQL Server 2008:NOLOCK如何用於CTE?

[英]SQL Server 2008: how does NOLOCK works for CTE?

我有全部使用NOLOCK的CTE。 但是,然后從使用子級的父級CTE中的那些CTE中進行選擇,就不會假定NOLOCK已被使用,因此不使用NOLOCK。 最終選擇也不使用NOLOCK。

像這樣:

with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1)

select * from cte2

還是我寫

with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1 (nolock))

select * from cte2 (nolock)

謝謝

您不需要外部nolock即可避免對tab1進行共享鎖定。 您可以通過設置一個SQL事件探查器跟蹤來輕松地驗證這一點,該跟蹤器捕獲locks類別中的各種事件,過濾SSMS連接的spid並嘗試這兩個版本。

nolock是一個非常危險的設置,您是否知道使用它的所有可能的缺點(臟讀,兩次讀取數據或根本不讀取數據)?

“外部”查詢上的NOLOCK也適用於任何內部查詢。 CTE只是一個宏,如視圖或內聯表udf:僅此而已。 因此,您實際上擁有了(忽略NOLOCK提示)

select * from (
               select * from (
                             select * from tab1
                             ) t1
               ) t2

MSDN上的表提示中的 “備注”下

所有鎖定提示都傳播到查詢計划訪問的所有表和視圖,包括視圖中引用的表和視圖。

在這種情況下,您只需要一個。 沒關系,在哪里。

重要的是您擁有JOIN的位置。 如果cte1是2個表的聯接,則每個表都需要它。 或在更高/更高級別指定一次。

哦,我將和其他所有人一起加入: NOLOCK是一個壞主意

最內層的nolock就足夠了,無需為外部選擇重復它。

您可以通過啟動事務而不結束它來測試它:

begin transaction
; with YourCte ( ...

然后,您可以使用Management Studio查看鎖。 他們會一直在那兒直到交易超時。

CTE的NOLOCK的工作方式與其他一切相同:導致結果不一致 請改用SNAPSHOT,請參閱SQL Server 2005基於行版本控制的事務隔離

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM