我在链接服务器上有一个大约 350m 行的表,我在其中添加了一个额外的 INT 列作为 PACKAGE 和 DOC2 上连接的结果的记录计数(external_identification)。由于表太大,我想分批处理更新,这样我就可以衡量进度并避免创建巨大的临时表。每列都有索引。
这是 CTE 发挥作用的一个很好的例子吗?老实说,他们让我对他们需要的写作方式感到困惑,很难想象......
这些表的结构如下:
ServerA(实用程序 SQL 服务器)
表:CLIP_IDs
列:Package_UUID nvarchar(255)、MessageExtractState tinyint、[count] int(350m 行)
ServerB(主数据库服务器)
表:PACKAGE
列:Package_UUID nvarchar(255)、Package_id bigint(650m 行)
表:DOC2
列:External_Identification nvarchar(255)、Package_id bigint(2b 行)
如果从一个服务器启动查询效率更高,则两个 SQL 服务器都是双向链接的。我感觉会从 ServerA 发出查询,因为执行计划似乎提供较少的远程查询。
我在 26 小时后停止了下面的查询,因为我认为我有语法逻辑错误。有人可以解释它是什么并提供任何建议吗?
从 ServerA 执行:
DECLARE @rowsUpdated INT
SET @rowsUpdated = 1
WHILE (@rowsUpdated > 0)
BEGIN
UPDATE CLIP_IDs
SET [Count] = x.[count]
FROM (
SELECT TOP 50000 c.package_uuid
,count(d.external_identification) AS [count]
FROM CLIP_IDs c
INNER JOIN ServerB.DATABASE.dbo.package p(NOLOCK) ON c.package_uuid = p.package_uuid
INNER JOIN ServerB.DATABASE.dbo.doc2 d(NOLOCK) ON p.package_id = d.package_id
WHERE c.messageextractstate = 1
AND c.[count] IS NULL
GROUP BY c.package_uuid
) x
SET @rowsUpdated = @@rowcount
PRINT N'Finished set of rows: ' + convert(VARCHAR, getdate(), 120)
END
根据您的权限,链接服务器可能会尝试在本地传输所有数据,然后进行过滤。参考
您可以通过首先将总聚合计数计算到本地服务器上的表中然后击败它来跳过这种痛苦。
首先尝试在 ServerB 上本地运行该查询,以了解理论吞吐量,而无需考虑您的网络。然后,您可以根据数据大小(临时表中每行 500 + 8)进行一些快速而肮脏的估计,然后这取决于您的网络。希望这都是本地网络。
如果在 ServerB 上运行和将其拉回来之间的时间明显不同,那么您可能需要使用 OPENQUERY 语法强制在远程服务器上加入。代码大约