SQL Server链接服务器性能:为什么远程查询如此昂贵?


14

我有两个通过链接服务器连接的数据库服务器。两者都是SQL Server 2008R2数据库,并且链接的服务器连接是使用当前登录名的安全上下文通过常规的“ SQL Server”链接建立的。链接的服务器都位于同一数据中心中,因此连接不成问题。

我使用以下查询来检查列的哪些值identifier可远程使用,但不能在本地使用。

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT DISTINCT
    identifier 
FROM LocalDb.schema.[TableName] 

在两个表上,列上的都是非聚集索引identifier。本地大约有260万行,远程只有54行。但是,在查看查询计划时,70%的执行时间专用于“执行远程查询”。此外,在研究完整的查询计划时,将使用估计的本地行数1代替2695380(这是仅选择后面的查询时的估计行数EXCEPT)。 执行计划 当执行此查询时,确实需要很长时间。

这让我感到奇怪:这是为什么?估算是“正确”的吗?还是在链接服务器上进行远程查询真的那么昂贵?


2
顺便说一句:您应该在索引搜索中查看“估计的执行次数”。估计的行数是每次执行输出的行数,除非计划进行了全面扫描,否则该行数与表本身中的行数无关。
马丁·史密斯

Answers:


9

您目前的计划对我来说似乎是最理想的计划。

我不同意其他答案中的说法,即它正在将2.6M行发送到远程服务器。

在我看来,该计划似乎是针对从远程查询返回的54行中的每一行,它都在对本地表执行索引查找以确定其是否匹配。这几乎是最佳计划。

给定表的大小,用哈希联接或合并联接替换将适得其反,而添加中间#temp表只会增加一个似乎没有任何好处的附加步骤。


6

连接到远程资源非常昂贵。期。

在任何编程环境中,最昂贵的操作之一就是网络IO(尽管磁盘IO会使它相形见))。

这扩展到远程链接服务器。调用远程链接服务器的服务器需要首先建立连接,然后需要在远程服务器上执行查询,返回结果并关闭连接。这一切都需要花费网络时间。


您还应该以这样一种方式来构造查询,即,您可以通过网络传输最少的数据。不要期望数据库为您优化。

如果要编写此查询,则将远程数据选择到表变量(或临时表)中,然后将其与本地表结合使用。这样可以确保仅传输需要传输的数据。

您正在运行的查询可以轻松地向远程服务器发送2.6M行,以便处理该EXCEPT子句。


好的,因此建立连接的启动成本很高。查询需要进行远程发送,处理(该网络不需要网络),最后将结果发送回并进行处理。但是通过网络连接发送数据不会花费几分钟,是吗?
vstrien 2012年

@vstrien-可能会。取决于网络连接,延迟,饱和度和其他因素。关键在于-它不是确定性的。

@vstrien-在我的答案中添加了更多信息。我相信所写的查询会将本地行发送到远程服务器进行处理。

2
您从哪里推断出它是从2.6M行发送到远程服务器的事实?我对远程查询运算符的计划没有太多经验,但看起来好像54列来自远程查询运算符,然后它正在对本地表进行反半联接。
马丁·史密斯

2
@Lieven-可能合乎逻辑,但从所示的计划来看并不正确。
马丁·史密斯

1

我不是专家,但是如果您使用的是Union,Except或Intersect,则不必使用“ Distinct”。根据LocalDb.schema。[TableName]中的值,可以提高查询性能。

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT 
    identifier 
FROM LocalDb.schema.[TableName]

0

Oded是正确的,性能问题是由将2.6M行发送到远程服务器引起的。

若要解决此问题,您可以使用临时表或内存表强制将远程数据(54行)发送给您。

使用临时表

SELECT  identifier 
INTO    #TableName
FROM    LinkedServer.RemoteDb.schema.[TableName]

SELECT  identifier
FROM    #TableName
EXCEPT
SELECT  DISTINCT identifier 
FROM    LocalDb.schema.[TableName] 

DROP    #TableName

在任何情况下,使用临时表都可能有助于基数估计,尽管嵌套循环对于仅54行似乎是合理的。
马丁·史密斯

使用临时表可以正确处理54行。但是如果两边都有大桌子,那就不可行了。对于两个大小相等的“巨大”桌子,您的解决方案是什么?在另一个数据库中创建UserTable?
vstrien 2012年

1
@vstrien-对于两个相等大小的大表并没有很好的解决方案。也许创建一个分布式分区视图可能会让您感兴趣,但是我对此没有任何经验。
Lieven Keersmaekers,2012年

0

我认为最好将远程表复制到要查询的服务器,然后在本地运行所有SQL。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.