web-dev-qa-db-ja.com

SQL Serverは2つのBULK INSERTを並行して実行できますか?

実行するクエリが2つあり、どちらも実行に約1分かかります。どちらのクエリも、一括挿入コマンドを使用して、テキストファイルからデータベースのテーブルにデータを挿入します。

データをインポートする2つのテーブルの場合、インデックス/トリガー/制約はなく、データをロードする2つの空のテーブルのみです。

2つのテキストファイルを読み込むには、それぞれに約2,000万行あります。

クエリ1:

Bulk insert table1
FROM 'table1.txt'  WITH
        (FIELDTERMINATOR ='|',
         ROWTERMINATOR = '0x0a',
         TABLOCK)

クエリ2:

Bulk insert table2
FROM 'table2.txt'  WITH
        (FIELDTERMINATOR ='|',
         ROWTERMINATOR = '0x0a',
         TABLOCK)

さまざまなシナリオでの実行時間を比較したい。

シナリオ1:1つのエディターで連続して実行される2つのクエリ:

  • クエリ1:1分18秒
  • クエリ2:1 m 2 s
  • 総実行時間は2分20秒です。

シナリオ2:same Studioインスタンスの別々のエディターの各クエリ、同時に実行:

  • クエリ1:2分36秒
  • クエリ2:2 m 09 d
  • 合計実行時間は2分40秒です。

シナリオ3:separate Studioインスタンスの各クエリ、同時に実行:

  • クエリ1:2分29秒
  • クエリ2:2分19秒
  • 合計実行時間は2分29秒です。

シナリオ2と3はクエリを同時に実行しているように見えますが、実行時間がほとんど変化しないのはなぜですか?すべてのシナリオで、CPU使用率は17%〜21%で、ディスク使用率は1秒あたり50MB〜70MBです。 CPUとディスクの使用量に大きな違いは見られません。

フードの下で何が起こっているのだろう? SQL Serverはこれらのクエリをどのように実行しますか? 3つのシナリオすべてで実行時間がほぼ同じになるのはなぜですか?それをスピードアップする方法はありますか?

Windows 10 64ビットでSQL Server 2016 Developer Editionを使用しています。私のラップトップにはクアッドコアi7とSSDがあります。

4つのクエリを一緒に実行してさらにシナリオをテストした後、CPUとディスクの使用率が低い原因として、Core i7のハイパースレッディングが考えられます。

  • 2つのエディターが2つのクエリを同時に実行すると、CPUの使用率は25%になります。

  • 4つのエディターが4つのクエリを同時に実行すると、CPUの使用率は最大で50%になります。

1つのクエリで1つのコアのみを使用する方法を知っていますか?私のThinkPad T460pはBIOSでそのようなオプションをサポートしていないため、ハイパースレッディングをオフにすることは私の選択肢ではありません。

2
Jason

このMSDNフォーラムのスレッド でDan Guzmanと長く有益な議論を行った後、基になるスケジューリングスキームがようやくわかりました。上記のスレッドから借りた簡単な答えは次のとおりです。

したがって、ここで何が起こっているかというと、2つのSSMS接続はどちらも、負荷が最小であるため、最初は同じスケジューラを使用しているということです。その後、BULK INSERTは両方とも同じスケジューラで実行されます。これが、SOS_SCHEDULER_YIELDが待機する理由です。

使用するスケジューラの選択は、クエリコストに基づいていません。 SQL Server(実際にはSOS)は基本的に sys.dm_os_schedulers のload_factor列を調べることにより、スケジューラ間でワークロードのバランスをとろうとします。

クエリ実行のために新しいタスクが作成されると、SOSは、セッションの最後の要求に使用したのと同じスケジューラを使用することを好みます。ただし、負荷係数が次の場合、別のスケジューラを使用します優先スケジューラーは、他のスケジューラーの平均負荷係数の特定の割合より大きい。

詳細については、上記のリンクを参照してください。

皆さんの熱心な助けに感謝します!

2
Jason