Sql-Server

MS SQL Server 上 UNION 查詢的鎖定和阻塞生存期

  • January 20, 2022

任何人都可以闡明鎖定在UNION查詢中的工作原理嗎?假設我有以下查詢,存檔表需要 1 分鐘才能執行,而非存檔表需要 5 秒。在整個查詢執行之前,是否對非歸檔表進行了任何鎖定?

SELECT
   COH.OrderNumber,
   COH.OrderType,
   COH.OrderDate,
   COL.Product,
   COH.Customer,
   SUM(COL.Quantity) Quantity,
   SUM(COL.Quantity* COL.Price) Ext
FROM

   CustomerOrderHeaders COH

   JOIN CustomerOrderLines COL ON COH.OrderNumber = COL.OrderNumber
GROUP BY

   COH.OrderNumber,
   COH.OrderType,
   COH.OrderDate,
   COL.Product,
   COH.Customer
UNION
ALL
SELECT

   COH.OrderNumber,
   COH.OrderType,
   COH.OrderDate,
   COL.Product,
   COH.Customer,
   SUM(COL.Quantity) Quantity,
   SUM(COL.Quantity * COL.Price) Ext
FROM

   CustomerOrderHeadersArchive COH

   JOIN CustomerOrderLinesArchive COL ON COH.OrderNumber = COL.OrderNumber
GROUP BY

   COH.OrderNumber,
   COH.OrderType,
   COH.OrderDate,
   COL.Product,
   COH.Customer

Transaction Basics文件中所述,使用鎖來保持事務隔離。如果鎖的釋放不會損害 ACID 屬性,則 SQL Server 沒有理由保持資源鎖定,事實上,越早釋放鎖對性能越好。

如果您看到Lock Modes,您會發現您的問題中的查詢很可能採用Shared Locks

共享 (S) 鎖允許並發事務在悲觀並發控制下讀取 (SELECT) 資源。當資源上存在共享 (S) 鎖時,沒有其他事務可以修改數據。 讀取操作完成後立即釋放資源上的共享 (S) 鎖,除非事務隔離級別設置為可重複讀取或更高,或者使用鎖定提示在讀取操作期間保留共享 (S) 鎖交易。

$$ emphasis added $$

所以不,您的第二個查詢需要更長的時間來執行這一事實並不意味著它會導致第一個上的表在整個UNION. Microsoft 有一個關於如何:確定哪些查詢持有鎖的文件,它使用擴展事件來展示鎖(獲取和釋放)。我在 AdventureWorks2016 數據庫上使用了建議的會話來檢查以下查詢:

SELECT ShoppingCartID, ModifiedDate
FROM Sales.ShoppingCartItem

UNION

SELECT SalesOrderDetailID, ModifiedDate 
FROM Sales.SalesOrderDetail 

實時數據

該查詢與您的查詢類似,您將能夠看到可互換地獲取和釋放鎖,而不是僅在開始時獲取並在結束時釋放。

據我所知,sql 在不再需要資源時釋放鎖,即在送出之後。它遵循兩相鎖定。

我建議嘗試啟動聯合查詢,然後在非存檔表上啟動更新,以查看更新是在 5 秒後還是在 1 分鐘後進行。

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