データベースの最適化において、統計情報の収集は通常、クエリプランの生成前に行われます。これは、統計情報収集後に大量の追加・削除・更新操作が発生し、それらの操作後に統計情報をタイムリーに再収集しない場合、プラン生成時に古い統計情報が使用され、正確な行数を推定できず、最適な実行計画を選択できない可能性があることを意味します。このような問題を解決するため、OceanBaseデータベースのオプティマイザーは、よりリアルタイムで正確な統計情報を取得するためのストレージ層による行数推定メカニズムを導入しています。
ストレージ層による行数推定メカニズム
クエリプランを生成する際、オプティマイザーはテーブルのインデックスに基づいて複数のベーステーブルのスキャンパス、すなわち「ベーステーブルパス」を生成します。OceanBaseデータベースのストレージ層は、これらのインデックスをツリー構造で格納しているため、プラン生成プロセスにおいて、各ベーステーブルパスに対して、オプティマイザーはテーブルの述語条件に基づいて複数のクエリ範囲領域(略称「QUERY RANGE」)を生成します。この設計の目的は、指定されたデータ領域を迅速にスキャンして取得し、無効なデータスキャンを回避することです。 オプティマイザーは、プラン生成時にベーステーブルパス上の関連するQUERY RANGEを事前にストレージ層に送信し、ストレージ層がこれらのQUERY RANGEの総行数を迅速に推定した後、結果をオプティマイザーに返すようにします。このプロセスにより、オプティマイザーはリアルタイムで正確な行数推定を得ることができ、このプロセスがストレージ層による行数推定です。
ストレージ層はリアルタイム統計情報を収集し、フィルターの再ソート機能をストレージ層で有効にするかどうかは、隠れたパラメータ_enable_filter_reorderingで制御されます。デフォルトでは有効であり、クエリ性能の向上に利用されます。
行数推定の制限
しかし、すべてのQUERY RANGEやパーティションがストレージ層による行数推定に使用されるわけではありません。ストレージ層による行数推定は時間コストが高い操作であるため、プラン生成全体の性能に影響を与えないよう、以下の2つの制限があります:
QUERY RANGEの制限:ベーステーブルパス上のQUERY RANGEの数が多すぎてはなりません。その数がシステム変数
range_index_dive_limitの設定値を超える場合、その数のQUERY RANGEをランダムに選択してストレージ層による行数推定を行います。同様に、QUERY RANGEの数がこの変数より少ない場合は、すべてのQUERY RANGEを選択して行数推定を行います。この変数が0の場合、システムは常にすべてのQUERY RANGEを選択し、制限は適用されません。パーティションの制限:パーティションテーブルの場合、クリッピング後のパーティション数がシステム変数
partition_index_dive_limitの制限を超えると、その数のパーティションをランダムに選択してストレージ層による行数推定を行います。パーティション数がこの変数より少ない場合は、常にすべてのパーティションを選択して行数推定を行います。この変数が0の場合も、同様にすべてのパーティションを選択します。
なお、ストレージ層による行数推定はベーステーブルパスにのみ適用され、JOINやGROUP BYなどの他の演算子には適用されません。 以前のバージョンでは、複数列IN述語が不正確な述語として認識される問題がありましたが、現在のバージョンではストレージ層による行数推定が可能になり、複数列IN述語を処理する際にも、複数のQUERY RANGEが存在する場合でも正確な行数推定が可能となり、クエリプランの最適化効果が向上しています。