2

異なるサーバーにある 2 つの SQL テーブル (Table1 と Table2) の特定の内容を比較する必要があります。

Table1 の各行を Table2 の内容全体と比較したいと考えています。

比較ロジックはちょっと複雑なので、C# で書く論理演算子を適用したいと思います。そのため、SQL クエリ自体で比較を行いたくありません。

私の懸念は、作業するデータのサイズが約 200 MB になることです。

ADO.Net を使用してデータを DataTable にロードし、メモリ上で比較を行うことを考えていました。

あなたは何をお勧めします?大量のデータを比較するためのパターンのようなアプローチは既にありますか?

4

6 に答える 6

2

200 MB は問題になりません。.NET アプリケーションは、それよりもはるかに多くのことを一度に処理できます。

それでも、表 1 には順方向専用のデータ リーダーを使用するでしょう。そうしない正当な理由がなく、必要なメモリの量を減らす必要があるからです。テーブル 2 は、慣れ親しんだ構造でメモリに保持できます。

于 2012-06-20T15:10:45.270 に答える
1

2つのSqlDataReaderを使用できます。それらは一度に1行しかメモリになく、順方向のみで、非常に効率的です。リーダーから行を取得した後、値を比較できます。これが例です。

MSDNを参照してください。

于 2012-06-20T15:08:06.927 に答える
1

実行している比較の実際のロジックによっては、これらのソリューションが適用できない場合があります。どちらのソリューションも、データを正しく並べ替えることに依存しています

1)二分探索。-バイナリ検索を使用すると、テーブル2のすべてをスキャンしなくても、テーブル2で一致する行を見つけることができます。これにより、比較の数が大幅に削減されます。

2)2つのテーブル間で重複/一致/欠落行を探している場合は、両方のテーブルを同じ順序で並べ替えることができます。次に、各テーブルの現在の行へのポインタを保持しながら、2つのテーブルを同時にループできます。テーブル1がテーブル2の「先行」している場合は、テーブル2のポインタを、それらが等しくなるか、テーブル2が先行するまでインクリメントするだけです。次に、テーブル2が先行すると、先行するまでテーブル1のインクリメントを開始します。このようにして、各テーブルの各レコードを1回ループするだけで、見逃した一致がないことが保証されます。

表1と表2が一致する場合、それは一致です。表1が先行している間、表2のすべての行が表1から「欠落」しており、その逆も同様です。

このソリューションは、行が互いに特定の範囲内にある場合などに何らかのアクションを実行する必要がある場合にも機能します。

3)テーブル2のすべての行に対して、テーブル1のすべての行に対して実際に何らかのアクションを実行する必要がある場合は、ネストされたループが2つだけであり、比較/作業を行う以外に、それを最適化するためにできることはあまりありません。可能な限り効率的。作業内容やボトルネックの場所によっては、マルチスレッド化できる可能性があります。

于 2012-06-20T15:20:20.383 に答える
1

最もスケーラブルなソリューションは、必要な比較を実行する SQLCLR 関数を作成することです。

おそらく、行ごとの比較は絶対に避けるべきです。ラウンドトリップによるネットワークの待ち時間と遅延により、実行が非常に遅くなります。

手っ取り早い解決策は、データをローカル ファイルに抽出してから比較を行うことです。これは、ネットワーク税を 1 回だけ支払うことになるためです。残念ながら、データベースのインデックスとクエリの最適化による高速化は失われます。

同様の解決策は、すべてのデータを一度メモリにロードしてから、辞書などのインデックス構造を使用してさらに高速化することです。データがメモリに収まるため、これはおそらく実行可能です。ネットワーク税を支払うのは 1 回だけですが、実行が速くなることで利益が得られます。

最もスケーラブルなソリューションは、必要な比較を実行する 1 つ以上の関数を作成するSQLCLRコードを作成することです。このようにして、ネットワークの負担を完全に回避し、メモリ内に独自の構造を作成して最適化することを回避し、インデックスと最適化を利用できます。

于 2012-06-20T15:16:13.990 に答える
0

数年前、私はデータベーステーブル比較ツールを作成しました。これは現在、データ比較と呼ばれるオープンソースプロジェクトです。

必要に応じて、ソースコードをチェックアウトできます。比較している2つのテーブルが同じ物理サーバー上にある場合は、SQLクエリを記述してこれを処理できるため、大規模な最適化を行うことができます。私はこれをデータ比較で「クイック比較」メソッドと呼んでおり、比較の両側で同じ接続文字列を共有している場合はいつでも使用できます。

ただし、2つの異なるサーバー上にある場合は、データをメモリにプルして、そこで行を比較する以外に選択肢はありません。SqlDataReadersを使用すると機能します。ただし、何が異なるか(テーブルAまたはテーブルBから欠落している行、異なる行など)を正確に知る必要がある場合は、複雑になります。そのため、私の方法はDataTablesを使用することでした。これは低速ですが、少なくとも必要な機能を提供します。

このツールの作成は、私にとって学習プロセスでした。おそらく、メモリ内の比較による最適化の機会があります。たとえば、データをディクショナリにロードし、Linqを使用して主キーから比較を行う方がおそらく高速です。Parallel Linqを試して、それが役立つかどうかを確認することもできます。また、Jeffrey L Whitledgeが述べたように、テーブルの1つにSqlDataReaderを使用し、もう1つはメモリに保存することもできます。

于 2012-06-20T15:20:43.033 に答える
0

クイック ETL/SSIS ジョブを使用して、データを同じデータベースにステージングできますか? これにより、より簡単に処理できるセット操作を行うことができます。そうでない場合は、メモリ内に 1 つのテーブルを持つ転送専用データ リーダーの推奨事項に同意します。

于 2012-06-20T15:17:18.387 に答える