我正在为 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
常量使用一个变量:或者,如果您的链接服务器配置为
RPC OUT
,请使用EXECUTE...AT
:在远程服务器上捕获的计划:
如果您在没有 RPC 的单个本地语句中需要它:
SQL Server 使用称为分布式查询(DQ) 的框架将您的 SQL 转换为远程服务器可以理解的形式。DQ 中的某些东西比其他东西更有效。
bit
数据类型总是有点奇怪。这当然是一个错误。如果您想报告它,您可以通过 Microsoft 支持以通常的方式进行报告,或者在https://aka.ms/sqlfeedback
在您的查询中,SQL Server 收集整个远程表,然后在本地应用筛选器。
以这种方式使用 openquery:
你也可以这样使用execute语句:
确保在链接服务器属性上将 RPC Out 设置为 True