Bufferテーブルとは、頻繁に挿入・削除が発生するテーブルを指します。ここでの「テーブル」にはインデックステーブルも含まれます(メインテーブルのインデックス列を更新すると、その変更はインデックステーブルにおいて削除および挿入操作として反映されます)。Bufferテーブル問題は、LSM-Treeメカニズムを採用したストレージエンジンに共通する課題です。LSM-Treeアーキテクチャのストレージエンジンでは、データはベースラインデータと増分データに分類されます。増分データは主にメモリ内のMemTableに存在し、ダンプによってディスクに書き込まれるダンプSSTableや、日次マージ時にディスクに書き込まれるベースラインSSTableを経由して管理されます。クエリ実行時には、MemTable、ダンプSSTable、ベースラインSSTableのデータを統合して最終的な結果が生成されます。このアーキテクチャでは、削除されたデータは削除フラグが立てられるだけであり、日次マージ前には物理的に削除されません。増分データに大量の削除フラグ付きデータが蓄積されると、上位アプリケーションから見て実際に存在する行数は少ないものの、範囲クエリ処理時には多くの削除フラグ付きデータを処理する必要が生じ、SQLの実行時間が理想的でない場合があります。また、Bufferテーブルのシナリオでは、オプティマイザーが非最適な実行計画を生成しやすくなります。
以上の分析から、Bufferテーブルには以下の特徴があると言えます:
トリガー条件:
テーブル内のデータが頻繁かつ大規模に更新される。
発生シナリオ:
アプリケーションロジックにおいて、大量の挿入・削除操作が発生する。
アプリケーションロジックにおいて、インデックス列への更新操作が頻繁に行われる。
直接的な現象:
テーブルの行数は多くないが、クエリの実行速度が非常に遅い。
問題の原因:
削除フラグが付いたデータにより、範囲クエリ処理時のデータ処理量が増加する。
実行計画が非最適である。
V$OB_SQL_AUDITビューでSQL問題と判断された場合、疑わしいSQLに範囲クエリの特徴が見られる場合は、そのテーブルがBufferテーブルであるかどうかをさらに確認できます。
説明
V$OB_SQL_AUDITの詳細については、V$OB_SQL_AUDIT(Oracleモード)およびV$OB_SQL_AUDIT(MySQLモード)を参照してください。
Bufferテーブル検出ロジック
内部ビューを用いてテーブル単位の総行数および挿入・更新・削除の各行数の増分を集計し、以下のいずれかの条件を満たす場合、Bufferテーブルと判断できます:
メインテーブルで大量の挿入と削除が同時に発生する:挿入行数の増分と削除行数の増分が近く、かつ挿入および削除の行数が多い。
インデックス列への大量更新が発生し、更新行数の増分が総行数に占める割合が高く、かつ更新行数が多い。
この問題は、以下の方法で解決できます:
より優れた実行計画がないか分析し、
CREATE OUTLINEステートメントを使用して手動でバインドします。マージを手動でトリガーし、削除されたデータを物理的に削除します。
より優れた実行計画がなく、マージによって解決する必要がある場合でも、できるだけ早くシステムを復旧する必要がある場合は、以下の手段を試すことができます:
スケールアウト
システムパラメータ
cpu_quota_concurrencyを調整するcpu_quota_concurrencyは、テナントの各CPUクォータが許可する最大並列数を設定します。詳細については、cpu_quota_concurrencyを参照してください。問題のSQLに対するレート制限(可能な限り小さなトラフィック、あるいは完全に停止させる)