はじめに
以下Microsoftのドキュメント から引用
SQL Server のラッチの競合とは
SQL Server のラッチの競合とは ラッチとは、インデックス、データ ページ、および B ツリー内の非リーフ ページのような内部構造など、メモリ内の構造の整合性を保証するために SQL Server エンジンによって使用される、軽量の同期プリミティブです。 SQL Server では、バッファー プール内のページを保護するためにはバッファー ラッチが使用され、バッファー プールにまだ読み込まれていないページを保護するためには I/O ラッチが使用されます。 SQL Server バッファー プール内のページのデータの書き込みまたは読み取りが行われるときは常に、ワーカー スレッドにおいて最初にそのページのバッファー ラッチを取得する必要があります。 バッファー プール内のページにアクセスするために使用できるバッファー ラッチには、排他的ラッチ (PAGELATCH_EX) や共有ラッチ (PAGELATCH_SH) など、さまざまな種類があります。 SQL Server によってバッファー プールにまだ存在しないページへのアクセスが試みられると、そのページをバッファー プールに読み込むための非同期 I/O がポストされます。 SQL Server で I/O サブシステムの応答を待機する必要がある場合は、要求の種類に応じて、排他 (PAGEIOLATCH_EX) または共有 (PAGEIOLATCH_SH) の I/O ラッチで待機が行われます。これは、別のワーカー スレッドにより互換性のないラッチを使用して同じページがバッファー プールに読み込まれるのを防ぐために行われます。 ラッチは、バッファー プール ページ以外の内部メモリ構造へのアクセスを保護するためにも使用されます。これらは、非バッファー ラッチと呼ばれます。ページ ラッチでの競合は、マルチ CPU システムで発生する最も一般的なシナリオであるため、この記事の大部分でこれらに焦点を当てています。
ラッチの競合は、複数のスレッドが同じメモリ内構造に対して互換性のないラッチを同時に取得しようとすると発生します。 ラッチは内部的な制御メカニズムであるため、それらを使用するタイミングは SQL エンジンによって自動的に決定されます。 ラッチの動作は決定論的であるため、スキーマの設計を含むアプリケーションの決定が、この動作に影響することがあります。
ドキュメントの内容だと長いので、これを調べて少し噛み砕いていこうと思います。
きっと最後までついて来れた方は↑がサラッと読めるようになるかも?
まずはじめにページとラッチについて整理していきたいと思います。
ページとは
SQL Serverがデータをアクセスする際の基本単位
ラッチとは
- ラッチはリソースの保護方法の一つ
- ラッチはSQL Server以外でも使われる用語
ページラッチとは
メモリにロードされた(バッファ上にキャッシュされた)ページ(データ領域)保護するための機構です。
ページラッチにはいくつかのモードがあります。
SQL Server のラッチモード
- KP -- 保持ラッチ (Keep Latch)
- 参照されている構造を破棄できないようにする
- スレッドでバッファーの構造を確認する必要がある場合に使用される
- SH -- 共有ラッチ
- データ ページの読み取りなど
- UP -- 更新ラッチ (Update Latch)
- 更新時に
- EX -- 排他ラッチ (Exclusive Latch)
- DT -- 破棄ラッチ (Destroy Latch)
このラッチのモードごとに同時取得できるものと、できないものがあります。
それが以下の表になります。
- 互換性がある場合は同じページに対して複数のラッチを同時に取得できる
- 互換性のないモードで保持されるラッチの取得を試みるとキューに配置される
ラッチ競合について
ここまでの説明のページラッチのモードの互換性によりラッチ競合が発生します。
例えば、同一のページに対してEXのラッチを取っているときに、SHのラッチの取得はできません。
このときにSHラッチが取得できないことをラッチ競合と言います。
EXやDTのページラッチでは他のラッチモードとの互換性が少ないので、長時間このラッチを取得しているとラッチ競合が起きやすくなります。
なのでラッチ競合が発生した場合は、EXやDTの占有時間を少なくできると良いでしょう。
もしくは、ページ単位なので異なるページへのアクセスになるようにデータの持ち方を検討するのも一案だと思います。