データベースの最適化において、統計情報の収集は通常クエリプランが生成される前に行われます。これは、統計情報の収集後に大量の追加・削除・変更操作が発生し、統計情報を適時に再収集しない場合、プラン生成時に古い統計情報が使用される可能性があり、その結果、行数の正確な推定ができず、最適な実行計画を選択できないことを意味します。このような問題を解決するため、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が存在する場合でも正確な行数の推定が可能となり、クエリプランの最適化効果が向上しました。