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