2

情報 (テーブル全体ではなく数列のみ) を含むテーブル (変更できない) を持つリモート Postgresql DB があります。テーブル (変更できる) を持つローカル SQL Server 2008 Express データベースに同期したいです。 .

今、私はこれを行うための効率的な方法を探しています。同期は 5 分ごとに実行されるため、毎回テーブル全体をリロードすると、回避しようとしている不要なトラフィックが大量に生成されます。

最新の ID を保存して、新しいものをすべて取得することを考えましたが、古いデータが変更される可能性があります (可能性は低いですが、まだ可能性はあります)。このままでは、変更されたデータを見逃すことになります。

同期は、ローカル SQL Server と同じマシンで実行されている C# プログラムによって行われます。

4

1 に答える 1

3

この問題には 2 つの解決策があります。賢く、変更のみを転送することもできますが、それにはソース データベースでの統合が必要です。あなたのデータベース管理者がそれを手伝ってくれると確信しています-潜在的に、すべてのタッチされた行を追跡するトリガー(ソーステーブルの主キーを使用)。このソリューションはかなりうまく拡張できますが、より複雑です。2 番目のオプションを検討する必要があると思います: 単純なブルート フォースです。

テーブル全体が 100MB で快適に収まります。これはあまりデータがありません。転送速度が 10MB/s であると仮定すると (これはまったく異常ではありません)、わずか 10 秒ですべてを転送できます。あなたが言うように、数列しか必要ない場合、データ転送の合計はかなり少なくなる可能性があります。5 分ごとに 10 秒の数値を使用すると、データを最新の状態に保つために 3% 程度の負荷がかかります。これは、ソース データベースに対する単純なクエリであり、特に負荷が大きくなることはないでしょう。データセットが非常に小さいため、すべてがメモリにキャッシュされます。

をご覧くださいSqlBulkCopy。この記事 ( Transderring data usingSqlBulkCopy ) は、あるデータベースから次のデータベースにデータをコピーするために使用する例です。ソース データ リーダーは何でもかまいません。たとえば、オブジェクトから計算されたデータを挿入するために使用しますが、特に簡単なケースは DbDataReader で、Postgresql から select ステートメントを取得できます。

SqlBulkCopyOptions残念ながら、デフォルトのオプションはあまり素晴らしいものではないので、役に立つものを指定したくなるでしょう。TableLock はおそらく悪いものではありません。また、これを並行して行う (つまり、1 つのテーブルに複数の一括挿入を行う) 場合は、インデックスに注意してください (デッドロックが発生する可能性があります)。バルク コピーのバッチ サイズを調整すると、スループットとメモリ使用量のトレードオフを最適化できますが、デフォルトでも問題なく動作する可能性があります。

概念的には、次のようにします。

  • ソース データベースとターゲット データベースへの接続を開く (を使用using)
  • SqlTransactionターゲット データベース接続を開始します
  • ターゲット テーブルからすべての行を削除します。
  • ソースからターゲットへの一括コピー (トランザクションを渡すことを忘れないでください)
  • 専念

このようにして、宛先テーブルをアトミックに更新します。

何をしようとしているのかはわかりませんが、これが何らかの形式のキャッシュである場合は、ターゲット SQL サーバーを完全に廃止し、データをオブジェクトの配列としてメモリに残すことを検討してください。読み取り専用データへのメモリ内アクセスは非常に高速で、データセットは簡単にメモリに収まります。

于 2013-01-31T12:23:05.313 に答える