あるサーバーから別のサーバーに(リンクサーバーを介して)データをエクスポートする必要があるとします。より効率的なステートメントはどれですか?
ソースサーバーで実行中:
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です。
あるサーバーから別のサーバーにデータをエクスポートする必要があるとします。
使うのが一番
データを移動するには、データの量/サイズとn/w帯域幅に応じて、リンクサーバーがパフォーマンスを停止します。
ソースサーバーで実行するか、ターゲットサーバーで実行する-ソースサーバーとターゲットサーバーの両方で、より速く、リソース消費量が少ないのはどれですか。
-ソースサーバーで実行:
INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()
これは、送信元サーバーでクエリを実行し、データを送信先サーバーにプッシュするため、PUSHINGデータと呼ばれます。これは高価な操作になります。
---ターゲットサーバーで実行中
INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')
送信先サーバーでクエリを実行し、送信元サーバーからデータをプルするため、これはデータのプルと呼ばれます。これは、前のものに比べてはるかに高速でリソース消費が少なくなります(プルされるデータの量によって異なります)。
プルメソッドの場合、SQLプロファイラーを使用すると、リンクサーバー(ソースサーバー)全体で単一のSQLステートメントが実行され、結果セットがソースサーバーから宛先サーバーにプルされます。これは、プッシュよりもパフォーマンスが大幅に向上します。方法。
注意すべきもう一つの点は:
リンクサーバー(servername.databasename.schema.tablename a.k.a分散クエリを使用する4つの部分の命名規則)とOPENQUERYの間では、一般にOPENQUERYが高速になります。なぜですか?
リンクサーバーの場合-クエリオプティマイザーは、クエリの用語を調べて実行プランを作成し、リモートクエリとローカルクエリに分割します。ローカルクエリはローカルで実行され、リモートクエリのデータはリモートサーバーから収集され、ローカルでスクラブされ、結合されて単一のレコードセットとしてエンドユーザーに提示されます。
OPENQUERYの場合-指定されたリンクサーバーで指定されたパススルークエリを実行します。 SQL Serverはパススルークエリを未解釈のクエリ文字列としてOLE DBデータソース)に送信します。したがって、SQLはクエリにいかなる種類のロジックも適用せず、推定を試みませんそのクエリが行うことは、指定されたクエリをそのままターゲットのリンクサーバーに渡すだけです。オープンクエリは、1つのクエリで複数のサーバーを参照していない場合に便利です。SQLは複数の操作に分割しないため、通常は高速です。受信した出力に対してローカルアクションを実行しません。
優れた参考資料:
効率をどのように測定していますか?どちらが速くなりますか?ターゲット上で消費するリソースが少なくなるのはどれですか?ソースで?これらの行の列はいくつの行とどのようなデータ型ですか?リンクサーバー経由でTVFを実行できますか? (ターゲットSQL 2008以降ですか?) ? TVFから取得する場合、このデータの1:1の移行をどのように保証しますか?
それらの質問は邪魔にならずに...
更新1
ETL(Extract-Transform-Load)を探しているようです。ソースからデータをプルし、必要な変換を適用して、それらをターゲットにロードできる SSIS(SQL Server Integration Services) をお勧めします。これはかなり簡単なパッケージのように思えます(変換によって異なります)。
従来の知識では、リンクサーバーアプローチはリンクに移動し、データをローカルサーバーにプルして、ローカルサーバーにロジック(フィルター、結合など)を適用します。リンクサーバーでデータをフェッチするためのオーバーヘッドが多少ありますが、処理の大部分はローカルで処理されます。
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;
SSMSでテンプレートを使用する方法については この回答 を参照してください。