0

大きな助けが必要です....

テーブルで、たとえば約 2,000,000 レコードに対していくつかの一括操作を実行する .net アプリケーションを作成する必要があります。アプリケーションを実行して、できるだけ多くの行を処理しようとする機会があります。アプリの複数のスレッドで一度に 2000 レコードを取得して処理できれば、さらに処理できるはずだと考えています。ただし、データベース サーバーではかなりのコストがかかります。私が聞いたところによると、db サーバーは強力なマシンであり、プレッシャーを処理できるはずです。

また、一度に 2000 行しか取得しないため、アプリケーションが処理の途中で終了した場合でも、どこから取得すればよいかがわかります。

だから、私が求めているのは...

1)別のスレッドに割り当てられないように、アプリで行を取得してそれらの行をロックするにはどうすればよいですか?

2) アプリが最後に中断したところから処理を再開できるようにするには、どのような種類のインテリジェンスをアプリにプログラムできますか?

ありがとう

KP

4

3 に答える 3

1

車輪を再発明するのではなく、SQL Server Integration Services (SSIS) を使用してこれを行う必要があります。特に 2008 リリースでは、これらのシナリオ向けに高度に最適化されています。

于 2009-07-31T19:07:15.340 に答える
1

SSIS にはこのようなシナリオ向けのインテリジェンスが多数組み込まれており、時間を投資するのにおそらく最善の策であるという John の意見に同意します。

レコードのような問題には、データを分割することによってアプローチします。物理的なストレージのパーティショニング (つまり、テーブルのパーティショニングの追加) について話しているのではなく、論理的な処理のパーティショニングについて話しているのです。2ミルを分割します。データアクセスレベルで利用できる条件に基づいて、N パーティションのレコード。インデックス付きの列を作成し、それぞれ独自のパーティションでチャーンを開始する N 個のプロセッサを割り当てます。アイデアは、同じ行にアクセスしようとする際にプロセッサが重複しないようにすることです。「プロセッサ」はスレッドである場合もあれば、非同期データベース アクセス メソッドを使用するワーカー アイテムをキューに入れている ThreadPool である場合もあります。

大きな問題は、多くの場合、適切なパーティショニング キーがないことです。このような場合、次のようなアドホック パーティショニングを実行できます。

with cte as (
   select top (@batchSize) *
   from myTable with (rowlock, updlock, readpast)
   where <record is ready to be processed>)
update cte
   set <mark record processing>
output inserted.*

秘訣は、select で使用されるロックのヒントです。force と updlock により、現在のプロセッサによる処理のためにレコードがロックされます。readpast ヒントを追加することにより、各プロセッサは、他のプロセッサによって既にロックされているレコードをスキップします。このようにして、各プロセッサは、処理が何であれ、処理するレコードの独自の @batchSize バッチを取得します。

これらのコメントはすべて、Web サービスの呼び出し、紙伝票の印刷など、データベースの外部に関係する処理に適用されることを理解することが重要です。処理がすべてデータベース内にある場合は、それを単一の T-SQL 更新として表現し、クエリ オプティマイザーが適切と思われる並列クエリを使用できるようにする必要があります。

于 2009-07-31T19:21:49.443 に答える