enq: TX – Index contention

目次

概要

Bツリー索引はデータを追加する過程で、リーフブロックがフルになるとスプリットでバランスをとります。セッションAがTXロックを排他ロックした状態でスプリットする途中でセッションBが該当リーフブロックを変更しようとする場合、セッションBはセッションAのトランザクションに対してTXロック共有モードで獲得するためにenq: TX – index contention イベントにて待機します。

enq: TX – index contention は通常の状況ではあまり発生しない待機イベントですが、主に同時に複数のセッションが索引のある表に対して 大量のDMLを実行する場合に発生します。また、索引が多くて索引を構成するカラムの値が大きくリーフブロックが頻繁にスプリットされる場合は性能低下の原因となります。特にシーケンスを使って値を採番する索引の場合、常に 値が最後のリーフブロックに集中されるため索引のスプリットが頻繁に発生することになります。これはBツリー索引の性格によって発生する現象で複数のセッションによる大量のデータを追加する場合buffer busy waits待機とともに、enq: TX – index contention 待機が発生することになります。

待機パラメータと待機時間

待機パラメータ

  • P1 : エンキュー情報
  • P2 : usn<<16 | スロット
  • P3 : シーケンス

待機時間

エンキュー待機イベントと同じく最大3秒まで待機します。もし、TXロックを獲得できなかったら獲得するまで待ちます。

チェックポイントとソリューション

逆キー索引の利用

シーケンスを利用して索引キーの値を作成する場合は右のリーフブロックへ集中的に追加されます。この場合に逆キー索引を使うと右のリーフブロックへ追加が集中する現象が解消できます。ただし逆キー索引を使う場合は 索引レンジスキャンが作動しないので気を付けてください。

索引キーカラムの変更

索引を構成するカラムの順序を変更して特定リーフブロックへ追加が集中する現象を解消することができます。 ただしアプリケーションの性格上、必ず特定キーを基準としてソートしないといけない場合はこういう方法を使うことはできません。

索引ブロックのサイズの変更

索引ブロックのサイズを大きく設定することも、一つの解決策になります。大きいサイズのブロックを使用する場合、一個のブロックに入るエントリの数が多いので、その分スプリットが少なくなるためです。ただ、ブロックのサイズが大きくなるとバッファロックに対する競合によってbuffer busy waits待機現象 が増加する場合もありますので、十分に気をつける必要があります。

分析事例

索引が多い表へ集中的なINSERTによる性能低下現象

同時に複数のセッションが索引の存在する特定表へ挿入INSERTを実行して以下のようにenq: TX – index contention 待機が発生しました。

マックスゲージ画面

INSERTされる表はユーザログを保存する表で、複数のユーザによる同時作業によって発生しました。データの参照ではなく記録を目的にする表なので、索引を無効にして問題を解決しました。