根本原因是SQL Server对远程视图基数估计失效,硬编码为10000行,导致优化器误选嵌套循环;而查远程基表可通过MSOLEDBSQL驱动获取真实统计信息,生成合理执行计划。

为什么跨链接服务器查视图比查基表慢得多
根本原因在于 SQL Server 对远程 VIEW 的基数估计(cardinality estimation)完全失效:它硬编码为固定值 10000 行,而对远程基表(如 LS1.AdventureWorks2019.Sales.SalesOrderDetail)能通过 MSOLEDBSQL 驱动读取远程统计信息和直方图,生成合理执行计划。一旦套上视图封装,优化器就“看不见”真实数据分布,极易选择嵌套循环(Nested Loops)而非哈希连接(Hash Join),导致大量重复远程调用。
绕过视图、直接查远程基表
这是最直接有效的提速手段,尤其适用于你控制远程数据库结构的场景:
- 把原查询
SELECT * FROM LS1.AdventureWorks2019.dbo.view1 WHERE SalesOrderID = 43659改成SELECT * FROM LS1.AdventureWorks2019.Sales.SalesOrderDetail WHERE SalesOrderID = 43659 - 确保远程表上有对应字段的索引(如
SalesOrderID),否则即使走基表,WHERE 条件也无法下推,仍会拉全表 - 若必须复用视图逻辑,可在本地建同义词(
CREATE SYNONYM)或内联表值函数(TVF),但注意 TVF 仍可能被当作黑盒处理
升级驱动并启用统计信息下推
旧驱动(如已弃用的 SQLOLEDB)不支持远程统计信息,必须换用 MSOLEDBSQL(Microsoft® OLE DB Driver 18 for SQL Server®):
- 创建 Linked Server 时,
@provider参数必须设为'MSOLEDBSQL',不能用'SQLNCLI11'或'SQLOLEDB' - 远程 SQL Server 实例需开启
remote data archive相关选项(默认已开),且数据库兼容级别 ≥ 120 - 确认远程表统计信息是更新的:
UPDATE STATISTICS Sales.SalesOrderDetail WITH FULLSCAN - 在查询中显式提示使用远程统计:
SELECT * FROM LS1.AdventureWorks2019.Sales.SalesOrderDetail OPTION (REMOTE)(仅限简单查询)
避免在远程端做复杂计算或 JOIN
Linked Server 的瓶颈常不在网络带宽,而在远程端 CPU 和内存——所有 WHERE、JOIN、GROUP BY 若无法下推,就会把中间结果全量拉到本地再算:
- 禁止写类似
SELECT a.*, b.Name FROM LS1.DB1.dbo.T1 a JOIN LS1.DB2.dbo.T2 b ON a.ID = b.T1ID,这会触发两次远程扫描 + 本地哈希 - 改用四部分命名 + 远程聚合:
SELECT ID, COUNT(*) FROM LS1.DB1.dbo.T1 GROUP BY ID,让计算发生在远程 - 如需多表关联,优先在远程库建好物化视图或索引视图,再通过 Linked Server 查这个预聚合结果
- 注意:远程视图里含
GETDATE()、NEWID()等非确定性函数时,整个查询会被标记为不可下推
真正卡住性能的,往往不是“连不上”,而是“连上了却不敢信它的估算”。视图跨服务器就像隔着毛玻璃看数据分布——你得亲手掀开那层玻璃,要么换更清晰的镜片(驱动),要么干脆绕过去看实物(基表)。

















