Sql-Server
為什麼 SQL Server 在更新位列時掃描所有行,即使是通過連結伺服器的主鍵
我正在為 SQL 連結伺服器的特定主鍵使用簡單的更新語句,如下所示
UPDATE t SET processed = 1, processed_on = GETDATE() FROM [LINKED\SERVER].DATABASE.dbo.FileQueue t WHERE t.FileId = '3b33eff6-fde1-4e8c-9c23-2dbd45f50222'
兩台伺服器都是 SQL Server 2019。表定義是
CREATE TABLE dbo.FileQueue ( FileId UNIQUEIDENTIFIER NOT NULL, Processed BIT NOT NULL, Processed_on DATETIME NULL CONSTRAINT PK_FileQueue PRIMARY KEY CLUSTERED ( FileId ASC ) )
Processed 列具有位類型。由於全表掃描,查詢速度很慢。
為什麼會這樣?當我從語句中刪除位列時,一切正常,讀取和更新單個遠端行。
該
Id
列是聚集的主鍵。我有很多具有相似鍵的表。我嘗試了
CONVERT
orCAST
函式,結果是一樣的。對於沒有位列的查詢,執行計劃非常好。
UPDATE t SET --processed = 1, -- any other columns can be added to be updated except bit processed_on = GETDATE() FROM [LINKED\SERVER].DATABASE.dbo.FileQueue t WHERE t.FileId = 'ABD4442F-8560-43B5-8B04-000000B2A626'
理想情況下,您將呼叫遠端伺服器上的儲存過程來進行此修改,並將 UUID 作為參數。
同時,嘗試為
bit
常量使用一個變數:DECLARE @true bit = 1; UPDATE t SET processed = @true, processed_on = GETDATE() FROM [LINKED\SERVER].DATABASE.dbo.Queue t WHERE t.Id = CONVERT(uniqueidentifier, '3b33eff6-fde1-4e8c-9c23-2dbd45f50222');
或者,如果您的連結伺服器配置為
RPC OUT
,請使用EXECUTE...AT
:DECLARE @id uniqueidentifier = {GUID '3b33eff6-fde1-4e8c-9c23-2dbd45f50222'}, @processed bit = 1, @processed_on datetime = GETDATE(); EXECUTE ( -- Parameterized statement N' UPDATE [DATABASE].dbo.Queue SET processed = ?, processed_on = ? WHERE Id = ?', --- Parameter values @processed, @processed_on, @id ) AT [LINKED\SERVER];
在遠端伺服器上擷取的計劃:
如果您在沒有 RPC 的單個本地語句中需要它:
UPDATE t SET processed = V.processed, processed_on = GETDATE() FROM [LINKED\SERVER].DATABASE.dbo.Queue AS t CROSS JOIN (VALUES(1)) AS V (processed) WHERE T.Id = CONVERT(uniqueidentifier, '3b33eff6-fde1-4e8c-9c23-2dbd45f50222');
SQL Server 使用稱為分佈式查詢(DQ) 的框架將您的 SQL 轉換為遠端伺服器可以理解的形式。DQ 中的某些東西比其他東西更有效。
bit
數據類型總是有點奇怪。這當然是一個錯誤。如果您想報告它,您可以通過 Microsoft 支持以通常的方式進行報告,或者在https://aka.ms/sqlfeedback