どちらがより効率的ですか:リンクサーバーから選択するか、リンクサーバーに挿入しますか?


32

あるサーバーから別のサーバーに(リンクサーバー経由で)データをエクスポートする必要があるとします。どのステートメントがより効率的ですか?

ソースサーバーでの実行:

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です。

回答:


29

あるサーバーから別のサーバーにデータをエクスポートする必要があるとします。

使用するのが最善です

  • すべてのデータでバックアップ/復元を使用する場合; BCP OUTおよびBCP INまたはSSIS
  • データのサブセット(一部のテーブルのみ)が必要な場合は、SSISまたはBCP OUTおよびBCP INを使用します

データを移動するには、データの量/サイズおよびn / w帯域幅に応じて、リンクサーバーはパフォーマンスを低下させます。

ソースサーバーで実行するか、ターゲットサーバーで実行する-どちらがより高速で、合計でより少ないリソースを消費しますか(ソースサーバーとターゲットサーバーの両方)?

-ソースサーバーでの実行:

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プロファイラーを使用すると、単一のSQLステートメントがリンクサーバー(ソースサーバー)全体で実行され、結果セットがソースサーバーからターゲットサーバーにプルオーバーされることがわかります。方法。

注意すべきもう1つの点は次のとおりです。

リンクサーバー(servername.databasename.schema.tablename aka Distributed Queriesを使用した4つの部分の命名規則)とOPENQUERYの間では、一般にOPENQUERYが高速になります。どうして ?

リンクサーバーの場合 -クエリオプティマイザーは、クエリの用語を参照して実行プランを作成し、リモートクエリとローカルクエリに分割します。ローカルクエリはローカルで実行され、リモートクエリのデータはリモートサーバーから収集され、ローカルでスクラブされ、結合されて単一のレコードセットとしてエンドユーザーに提示されます。

OPENQUERYの場合 -指定されたリンクサーバーで指定されたパススルークエリを実行します。SQL Serverは、パススルークエリを未解釈のクエリ文字列としてOLE DBデータソースに送信します。したがって、SQLはクエリにいかなる種類のロジックも適用せず、そのクエリが何を行うかを推定しようとせず、指定されたクエリをそのままターゲットリンクサーバーに渡します。開いているクエリは、1つのクエリで複数のサーバーを参照していない場合に便利です。SQLは複数の操作に分割せず、受信した出力に対してローカルアクションを実行しないため、一般に高速です。

優れた読書リファレンス:


8

効率をどのように測定していますか?どちらが速くなりますか?ターゲットで消費するリソースが少ないのはどれですか?ソースで?これらの行の列はいくつの行とどのようなデータ型ですか?リンクサーバーを介して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でテンプレートを使用する方法については、この回答を参照できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.