0

次の設定と要件を備えた新しいプロジェクトを用意してください:-

私のクライアントは、オフィスに MSSQL 2005 サーバー (A) を持っています。彼らのベンダーは、リアルタイムのトランザクション データを含む MSSQL 2005 サーバー (B) を世界の別の場所に持っています。私のクライアントは、営業時間外に毎日 (B) から (A) にデータをロードしたいと考えています。彼らは (B) へのデータリーダー アクセス権を持っていますが、それだけです。ベンダーはレプリケーションやログ配布などを行いません。私のクライアントは、独自のレポート/キューブを実行できるように独自のデータを取得する責任があります。

私が使用したスクリプトは次のとおりで、分散 TSQL と (B) へのリンク サーバーを使用しています。

DECLARE @sqlCommand        VARCHAR(2000)
DECLARE @LastProcessedDate DATETIME

-- run the following code for Table 1 to Table XX

SELECT @LastProcessedDate = LastProcessedDate 
  FROM [ProcessControl] 
 WHERE TableName = 'table_1'

SET @sqlCommand = 'INSERT INTO Table1 
                   SELECT * 
                     FROM OPENQUERY(VendorsLinkedServerName, 
                          ''SELECT * 
                              FROM Table1 
                             WHERE LastModified >= '''' + @LastProcessedDate + '''')'

EXEC @sqlCommand

丸 1 日分のデータに対して 10 個の最大テーブルの最初の試行を行いましたが、1 時間かかりすぎました。また、テストのために、テーブルの主キー (1 ~ 4 個の BIGINT 列で構成される) を除くすべてのインデックスと制約を既に削除しました。ロード時間を短縮したり、データをロードしたりする方法について何か提案はありますか?

編集: select ステートメントがこのように記述された理由を疑問に思う場合に備えて、追加するだけです。上記の例では、(A) の Table1 は ETL データベースにあり、その後、データが比較されて、実際の挿入/更新/削除が決定されます。 (A) のレポート データベース

4

5 に答える 5

1

一方向 (ダウンロードのみ) の同期を探しているようです。最高の信頼性を得るために、ベンダー (B) に ROWVERSION 列を追加するよう依頼します。これは、DateTime または DateTimeOffset よりも少し安全です。

あなたのクエリに関しては、私は次のようなことをしました:

INSERT INTO dbo.Table1
(
    Field1,
    Field2,
    Field3
)
SELECT
    T1.Field1,
    T1.Field2,
    T1.Field3
FROM [LinkedServer].[DatabaseName].[dbo].[Table1] T1
WHERE T1.Version > @LastAnchor

CreatedVersion と UpdatedVersion を使用し、必要に応じて削除用の廃棄行を使用して、スキーマが同じである場合は、ETL フェーズ全体をスキップできます。Sync Frameworkは、この多くを単純化しますが、概念を使用して独自のものを比較的簡単に作成することができます。ルールは次のとおりです。

-- get inserts in dependency order
INSERT INTO ...
SELECT ...
FROM ...
WHERE CreatedVersion > @LastAnchor
-- get updates in dependency order
UPDATE [dbo].[Table1]
SET ...
FROM [LinkedServer].[DatabaseName].[dbo].[Table1] T1
WHERE [dbo].[Table1].[PK] = T1.[PK]
    AND T1.CreatedVersion <= @LastAnchor
    AND T1.UpdatedVersion > @LastAnchor
-- get deletes (if you need them)
DELETE T
FROM [dbo].[Table1] T
JOIN [LinkedServer].[DatabaseName].[dbo].[Table1_Tombstone] T1
    ON T.[PK] = T1.[PK]
    AND T1.DeletedVersion > @LastAnchor

これらすべてのクエリを適切に実行するには、CreatedVersion、UpdatedVersion、および DeletedVersion 列にインデックスを付ける必要があります。

上記のすべてのロジックは DateTime または RowVersion に対して機能しますが、RowVersion の方が正確であり、進行中のトランザクションに関して 2005 SP2 で解決されるいくつかの問題があります。基本的に、SQL 2005 SP2 および SQL 2008 では、最大アンカーを MIN_ ACTIVE_ROWVERSION() - 1 に設定し、その間のものを照会します。理由の詳細については、MSDN ノートを参照してください。

いくつかとは異なり、UpdatedVersion をクラスター化インデックスにしないことを強くお勧めします。これは、更新が行われたときにページ上のデータを常に再ソートする必要があるためです。ベンダーにそれを推奨すると、ばかげているように見えます。

Sync Framework を使用する利点の 1 つは、WCF を使用してデータ呼び出しを行い、毎日の終わりに大規模な同期を行うのではなく、一定の間隔で小規模な同期を行うことができることです。これには、ベンダーがデータベース アクセスを提供する WCF サービスを提供するか、少なくともホストする必要があります。必要に応じて、より頻繁に実行される小規模な同期をサポートしながら、Sync Framework でリンク サーバーを使用することもできます。

于 2009-09-13T15:00:04.247 に答える
1

残念ながら、最大の速度低下は単にネットワークの遅延であり、それについてできることはあまりないと思います。

ただ、ひとつ考えがあります。ターゲット テーブルの主キー (クラスター化インデックス) に一致する SELECT ステートメントに ORDER BY 句を追加してみてください。これにより、挿入中にテーブルを並べ替える必要が減る可能性があります。

また、テーブルはいくつあり、時間はどれくらいありますか? 1 時間で最大 10 のテーブルを処理した場合、90/10 のルールが適用され、他のすべてのテーブルを合わせてもそれらの 10 よりも時間がかからないことに気付くかもしれません。

于 2009-09-12T16:29:50.600 に答える
0

パフォーマンスは、あなたが取っているアプローチではなく、ネットワーク遅延によるものですか? どのようなボリュームを扱っているかなど

彼らはレプリケーションやログ配布を行わないことに注意しますが、一括挿入を行うために相手側で自動化されたルーチンのために圧縮して送信できるスケジュールされた一括エクスポートを行うように彼らに相談できますか?

于 2009-09-12T16:09:12.493 に答える
0

クエリをローカルで試して (またはクエリをローカルで実行してみて)、所要時間を確認してください。Chris が指摘したように、それはネットワーク レイテンシである可能性があります。ベンダー側で SSIS パッケージを展開する能力はありますか? その場合、データを抽出して圧縮し、FTP タスクまたは別のメカニズムを介して送信し、最後にデータを解凍/挿入できます。

于 2009-09-12T16:20:12.383 に答える
0

Chris W が示唆しているように、スローダウンがどこにあるかを判断するためにいくつかのテストを実行することをお勧めします。

たとえば、クエリを実行して情報をファイルにダンプし、時間を計ります。

クエリを実行するだけの時間で、取得しているデータを無視して、データの転送にかかる時間を確認します。

次に、転送する時間と、データベースをループから外すとどうなるかがわかります。

次に、最善の行動方針を決定できます。

また、多数の個別のクエリを実行することもできます。

したがって、1 つの大きなテーブルから転送するのにかかる時間。

次に、大きなテーブルに対して 5 つのクエリを実行し、何が起こるかを確認します。

可能であれば、複数の同時接続を作成できるかどうかを確認し、データをすばやく d/l して空のデータベースにダンプし、ローカル コピーからデータベースにコピーしてインデックスの代価を支払うことをお勧めします。

ただし、操作にかかる時間を確認するための数値が得られるまで、これはすべて無意味です。

于 2009-09-12T16:22:34.437 に答える