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

Gui*_*rez 32 sql-server-2005 sql-server insert linked-server

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

在源服务器中执行:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()
Run Code Online (Sandbox Code Playgroud)

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

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

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

Kin*_*hah 30

假设我必须将数据从一台服务器导出到另一台服务器。

最好是使用

  • 如果您希望所有数据都使用备份/还原;BCP 输出和 BCP 输入或 SSIS
  • 如果您想要数据子集(仅限某些表),请使用 SSIS 或 BCP OUT & BCP IN

要移动数据,根据数据的数量/大小和 n/w 带宽,链接服务器会降低性能。

在源服务器中执行或在目标服务器中执行 - 哪一个会更快并且总共消耗更少的资源(源服务器和目标服务器)?

-- 在源服务器中执行:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()
Run Code Online (Sandbox Code Playgroud)

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

--- 在目标服务器中执行

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

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

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

另一点需要注意的是:

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

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

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

优秀的阅读参考:


swa*_*eck 8

你如何衡量效率?哪个会更快?哪一个会在目标上消耗更少的资源?在源头上?这些行中的列是多少行和什么样的数据类型?您确定可以通过链接服务器执行 TVF (目标是 SQL 2008 或更高版本?)?如果您从 TVF 中提取,您如何确保这些数据的 1:1 迁移?

有了这些问题...

更新 1

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


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

OPENQUERY 方法将处理放在远程服务器上,本地服务器将接收“过滤结果”。

似乎即使您可以通过链接服务器执行 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;
Run Code Online (Sandbox Code Playgroud)

您可以参考此答案了解如何在 SSMS 中使用模板。