1
SQL ServerのLOBデータのパフォーマンスを削除する
この質問は、このフォーラムスレッドに関連しています。 ワークステーションでSQL Server 2008 Developer Editionを実行し、「アルファクラスター」と呼ばれるEnterprise Editionの2ノード仮想マシンクラスターを実行しています。 varbinary(max)列のある行を削除するのにかかる時間は、その列のデータの長さに直接関係します。最初は直感的に聞こえるかもしれませんが、調査の後、SQL Serverが実際に一般的に行を削除し、この種のデータを処理する方法についての私の理解と衝突します。 この問題は、.NET Webアプリケーションで発生している削除タイムアウト(> 30秒)の問題に起因していますが、この説明のために単純化しています。 レコードが削除されると、SQL Serverは、トランザクションのコミット後、ゴーストクリーンアップタスクによってクリーンアップされるゴーストとしてマークします(Paul Randalのブログを参照)。varbinary(max)列にそれぞれ16 KB、4 MB、および50 MBのデータを含む3つの行を削除するテストでは、データの行内の部分を含むページとトランザクションでこれが発生しますログ。 奇妙なことに、削除中にすべてのLOBデータページにXロックが設定され、PFSでページの割り当てが解除されます。これは、トランザクションログ、sp_lockおよびdm_db_index_operational_statsDMV の結果(page_lock_count)で確認できます()。 これらのページがバッファキャッシュにまだない場合、ワークステーションとアルファクラスタでI / Oボトルネックが発生します。実際、page_io_latch_wait_in_ms同じDMVからの削除は実質的に削除の全期間であり、page_io_latch_wait_countロックされたページの数に対応します。ワークステーション上の50 MBファイルの場合、空のバッファーキャッシュ(checkpoint/ dbcc dropcleanbuffers)で開始すると3秒以上になりますが、断片化が重く、負荷がかかっている場合はより長くなることは間違いありません。 私はそれがキャッシュ内のスペースを割り当てているだけではないことを確認しようとしました。checkpointメソッドの代わりに削除を実行する前に、他の行から2 GBのデータを読み取りました。これは、SQL Serverプロセスに割り当てられている以上のものです。SQL Serverがデータをシャッフルする方法がわからないため、それが有効なテストであるかどうかはわかりません。私はそれが常に新しいものを支持して古いものを押し出すと思いました。 さらに、ページを変更することさえしません。これは私が見ることができますdm_os_buffer_descriptors。削除後、ページはきれいになりますが、変更されたページの数は、小規模、中規模、および大規模の3つの削除すべてで20未満です。またDBCC PAGE、ルックアップされたページのサンプリングの出力を比較しましたが、変更はありませんでした(ALLOCATEDPFSからビットのみが削除されました)。単に割り当てを解除します。 ページの検索/割り当て解除が問題の原因であることをさらに証明するために、vanilla varbinary(max)の代わりにfilestream列を使用して同じテストを試みました。削除は、LOBサイズに関係なく一定の時間でした。 だから、最初に私の学術的な質問: Xロックするために、SQL ServerがすべてのLOBデータページを検索する必要があるのはなぜですか?これは、メモリ内でロックがどのように表されているか(ページと一緒に保存されている)の詳細にすぎませんか?これにより、完全にキャッシュされない場合、I / Oの影響はデータサイズに大きく依存します。 割り当てを解除するためだけにXがロックされるのはなぜですか?割り当て解除ではページ自体を変更する必要がないため、行内部分でインデックスリーフのみをロックするだけでは十分ではありませんか?ロックが保護するLOBデータを取得する他の方法はありますか? この種の作業専用のバックグラウンドタスクが既にあるのに、なぜページの割り当てをまったく解除するのですか? そしておそらくもっと重要なのは、私の実際的な質問です: 削除の動作を変える方法はありますか?私の目標は、ファイルストリームと同様に、サイズに関係なく一定時間で削除することです。ファイルストリームでは、事後のバックグラウンドでクリーンアップが行われます。構成の問題ですか?奇妙に物を保管していますか? 以下に、説明したテスト(SSMSクエリウィンドウで実行)を再現する方法を示します。 CREATE TABLE [T] ( [ID] [uniqueidentifier] …
16
sql-server