当前位置: 首页>>技术教程>>正文


哪一个更有效:从链接服务器中选择还是插入链接服务器?

webfans 技术教程 , , , , 去评论

问题描述

假设我必须将数据从一个服务器导出到另一个服务器(通过链接服务器)。哪种陈述会更有效率?

在源服务器中执行:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()

或者在目标服务器中执行:

INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
    'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')

哪一个更快,消耗的资源总量更少(源服务器和目标服务器)?两台服务器都是SQL Server 2005。

最佳解决思路

Suppose I have to export data from one server to another.

最好是使用

  • 如果您希望所有数据都使用备份/恢复; BCP OUT& BCP IN或SSIS

  • 如果您想要数据子集(仅限某些表),请使用SSIS或BCP OUT& BCP IN

要移动数据,取决于数据的数量/大小和n /w带宽,链接服务器将终止性能。

Executing in source server Or executing in target server – Which one will be faster and consume fewer resourcers in total (both source and target server)?

– 在源服务器中执行:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()

当您在源服务器上执行查询并将数据推送到目标服务器时,这称为PUSHING Data。这将是昂贵的操作。

—在目标服务器中执行

INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
    'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')

当您在目标服务器上执行查询并从源服务器提取数据时,这称为PULLING Data。与前一个相比,这将更快,更少资源(取决于拉动的数据量)。

在pull方法的情况下,使用SQL事件探查器,您将看到在链接服务器(源服务器)上执行单个SQL语句,并且结果集从源服务器切换到目标服务器,这比PUSH有巨大的性能提升方法。

另一点需要注意的是:

在链接服务器(4部分命名约定使用servername.databasename.schema.tablename a.k.a分布式查询)和OPENQUERY之间,通常OPENQUERY会很快。为什么?

对于链接服务器 – 查询优化器通过查看查询命名法创建执行计划,并将其分解为远程和本地查询。本地查询在本地执行,远程查询的数据从远程服务器收集,在本地擦除,组合在一起并作为单个记录集呈现给最终用户。

对于OPENQUERY – 在指定的链接服务器上执行指定的pass-through查询。 SQL Server将pass-through查询作为un-interpreted查询字符串发送到OLE DB数据源。因此,SQL不会对查询应用任何类型的逻辑,也不会尝试估计查询将执行的操作,它只是将指定的查询原样传递给目标链接服务器。当您未在一个查询中引用多个服务器时,打开查询很有用。它通常很快,因为SQL不会将其分解为多个操作,并且不会对接收的输出执行任何本地操作。

优秀的阅读参考:

次佳解决思路

你如何衡量效率?哪一个会更快?哪一个会在目标上消耗更少的资源?在源头上?这些行中的列有多少行和哪种数据类型?您确定可以通过链接服务器(is the target SQL 2008 or later?)执行TVF吗?如果你从TVF中拔出,你如何确保这些数据的1:1迁移?

把这些问题放在一边……

更新1

听起来你正在寻找ETL(Extract-Transform-Load)。我建议使用SSIS (SQL Server Integration Services),您可以从源中提取数据,应用所需的转换,然后将它们加载到目标中。这听起来像是一个非常简单的包(取决于转换)。


传统观点认为,链接服务器方法将转到链接,将数据拉到本地服务器,然后在本地服务器上应用任何逻辑(过滤器,连接等)。在链接服务器上获取数据有一些开销,但大部分处理将在本地处理。

OPENQUERY方法将处理放在远程服务器上,本地服务器将接收”filtered results”。

看起来即使您可以通过链接服务器执行TVF,您也会遇到两个世界中最糟糕的情况,远程处理和本地处理(假设您有额外的逻辑应用于该集合)。

根据您决定如何继续前进,我还将研究OPENQUERY作为批量导入/导出数据的方法。

说完所有这些……

如果SQL Server上的源和目标(以及目标不是较低版本),为什么不进行备份和还原数据?这将是真正的数据迁移。这是给你的一些代码。

BACKUP DATABASE <DatabaseName, sysname, DatabaseName>
TO DISK=N'<backup_location, varchar, BackupLocation>.bak'
WITH INIT, FORMAT, COMPRESSION, COPY_ONLY

RESTORE DATABASE <NewDatabaseName, sysname, NewDatabaseName>
FROM DISK = N'<backup_location, varchar, BackupLocation>\
    <DatabaseName, sysname, DatabaseName>.bak'
WITH 
    MOVE '<DataFileName, sysname, DataFileName>' TO '<DataMDFPath, nvarchar(600), DataMDFPath>',
    MOVE '<LogFilePath, sysname, LogFilePath>' TO '<LogLDFPath, nvarchar(600), LogLDFPath>',
    REPLACE;

关于如何在SSMS中使用模板,可以参考this answer

参考资料

本文由朵颐IT整理自网络, 文章地址: https://duoyit.com/article/3049.html,转载请务必附带本地址声明。