web-dev-qa-db-ja.com

大量のtempdbログの書き込み、読み取りなし

私には奇妙に見える行動に遭遇しています。 Windows 7(テスト用)でSQL Server 2008 Enterprise、32ビット(クアッドコア2)を使用しています。

2つのテーブル変数を使用するストアドプロシージャがあります。 1つは約2または3行が挿入され、もう1つは0〜100行が挿入されます。次に、2番目からおそらく20〜60行を選択し、それだけです。

パフォーマンスはかなり速いです。クエリの実行をループする単純なアプリを作成しました。1つのスレッドで1300 /秒、4つのスレッドで約4000を実行できます。

tempdbを入力してください:リソースモニターを開いて何が起こっているかを確認すると、tempdbログファイルへの書き込みが多いことがわかります。 (2つの異なる物理ディスクに2、100MBを作成しました-それらは100MBを超えて成長していないようです。)zero読み取りアクティビティがあります-全体DBはRAMに収まります。

クエリを実行するシングルスレッドでは、tempdbログファイルへの書き込みは約3MB /秒です。これを増やすと、ログファイルあたり最大20MB /秒になります。

SQLアクティビティモニターで、5つのスレッドを使用している場合、「待機時間」の「ログ」が300ミリ秒/秒を超えます。 3スレッドでは、25ms /秒になります。

質問:何が起こっているのですか? tempdbログへのSQLの書き込みがおかしなように見えるのに、読み取りがゼロになるのはなぜですか(リソースモニターまたはアクティビティモニターに読み取りアクティビティが表示されません)。非テスト環境では、40MB /秒の書き込みが余分にあると、全体的なパフォーマンスに悪影響を与える可能性があるように思われます。

テーブル変数(@foo)が常にメモリに格納されるとは限らないことは知っていますが、tempdbがこれらすべてをログに記録する必要がある理由について混乱しています。どうすればそれが何をしているのかトラブルシューティングできますか? tempdbのログをRAMディスクなどに置くことはできますか?他のポインタはありますか?

前もって感謝します!

2
MichaelGG

これは典型的なログです 先行書き込み 動作。データベースでページが更新されると、更新は最初にログに書き込まれ、次にメモリ内のページに適用されます。チェックポイントが発生するまでページはメモリ内でダーティのままになり、チェックポイントが発生するとディスクに書き込まれます。リカバリとロールバックをサポートするには、更新の前にログを書き込む必要があります。これらの2つのいずれかが発生しない限り(リカバリまたはロールバック)、ログを再度読み取る必要はありません。したがって、表示される動作は、tempdbのページを変更するシステムで一般的です。ロールバックが発生した場合にのみログの読み取りが表示されます(tempdbの回復は発生しないため)。

さらに興味深い質問は、tempdbで非常に多くのページ更新が発生する理由です。典型的な原因は、直接更新(ASPを使用したtempdbのセッション状態など)または間接更新(クエリプランのスプールと並べ替え)のいずれかです。

1
Remus Rusanu