データベースにおけるクエリのリライト(Query Rewrite)とは、あるSQLをより最適化しやすい別のSQLに変換することを指します。
OceanBaseデータベースでは、ルールベースのリライトとコストベースのリライトの2種類のクエリリライトルールを提供しています。
ルールベースのクエリリライト は常にSQLを「良い」方向にリライトし、そのSQLの最適化の余地を広げます。例えば、サブクエリを結合操作に変換することは、典型的なルールによるリライトであり、オプティマイザーが考慮する実行計画を、ネステッド・ループ・ジョインに限定されず、Hash JoinやMerge Joinなどに拡張します。
コストベースのクエリリライト は必ずしもSQLを「良い」方向にリライトできるわけではなく、コストモデルに依存してリライトを実行すべきかどうかを評価します。例えば、OR-Expansionはコスト駆動型のリライト戦略です。
データベースでは、リライトルールを適用するには特定の条件を満たす必要があり、異なるルール間で相互にトリガーされる場合もあります。OceanBaseデータベースは、ルールによるリライトを複数のセットに分け、反復的な手法を用いて各セットを処理し、さらなるリライトが不可能になるか、事前設定された反復回数の制限に達するまで続けます。コストベースのリライトルールも同様の反復的な方法で処理されます。
注目すべき点は、コストベースのリライトがルールベースのリライトをトリガーする可能性があるため、全体として、OceanBaseデータベースのクエリリライトは実際にはこれら2つの戦略を反復的に適用することで行われているということです。
SQLクエリのリライトルール
OceanBaseデータベースがサポートするクエリのリライトルールは、ルールベースのリライトとコストベースのリライトです。
データベースクエリの最適化において、ルールモデルとコストモデルは、クエリがどのようにリライトされ、実行計画がどのように選択されるかを決定する2つの重要な要素です。これらの目的は、SQLクエリのパフォーマンスを向上させることです。以下では、一般的なルールモデルとコストモデルについてそれぞれ紹介します。
ルールベースのモデル(ルールに基づくクエリのリライト)
ルールベースのモデルは、通常、固定されたヒューリスティックなルールに基づいてクエリをリライトします。以下は、代表的なルールによるリライト戦略です:
サブクエリ関連のリライト:
- ビューのマージング(View Merging):ビュー内の埋め込みクエリをメインクエリに統合し、階層を削減して実行効率を向上させます。
- サブクエリの展開(Subquery Unnesting):サブクエリの展開とは、
WHERE条件内のサブクエリを親クエリに昇格させ、結合条件として親クエリと並列して展開することです。変換後、サブクエリは存在せず、外部の親クエリは複数テーブルの結合に変わります。
ANY/ALLのMAX/MINによるリライト**:ANYまたはALL演算子を含むサブクエリを、集約関数MAXまたはMINを使用する形にリライトし、インデックスの適用やより効率的な実行戦略を可能にします。
外部結合の除去(Outer Join Elimination):
- 外部結合の結果が最終結果セットに影響しない場合、外部結合を除去し、内部結合または単純な
SELECTに変換してクエリを簡略化します。
- 外部結合の結果が最終結果セットに影響しない場合、外部結合を除去し、内部結合または単純な
条件の簡略化リライト**:
HAVING条件の除去:クエリに集計操作やGROUP BYがない場合、HAVING条件をWHERE条件に統合し、HAVING条件を削除することで、HAVING条件をWHERE条件で一元的に管理し、さらなる最適化を図ることができます。- 等価関係の導出:等価関係の導出とは、比較演算子の伝搬性を利用して新しい条件式を導き出し、処理する行数を減らすか、より効果的なインデックスを選択することを指します。
- 常に真/偽の部分の除去:クエリ条件から常に真または常に偽の部分を除去し、クエリロジックを簡略化します。
非SPJ(Select-Project-Join)のリライト**:
- 冗長なORDER BYの除去(Redundant Order By Elimination):クエリ結果に特定の順序が不要であるか、ソートが無効な場合、ソート操作を除去します。
- LIMITのサブクエリへのプッシュダウン:
LIMITがサブクエリに適用可能で最終結果に影響しない場合、LIMITをサブクエリにプッシュダウンして処理する行数を減らします。 - 外部結合または交差結合へのLIMITのプッシュダウン:
LIMITを外部結合または交差結合の適切な部分に適用して、不要な行処理を削減します。 - DISTINCTの除去:結果セット内の行が既に一意であることが保証される場合、
DISTINCT操作を除去します。 - MIN/MAXのリライト:適切な場合、クエリをより効率的な形式にリライトして
MINまたはMAX値を計算します。例えば、インデックスアクセスを通じて行います。
コストモデル(コストに基づくクエリの再構成)
コストモデルは、コスト推定に依存して最適なクエリ実行計画を選択します。以下は、OceanBaseデータベースがサポートするコスト評価に基づく戦略です:
- OR-Expansion:OR条件を含む述語を複数の独立したクエリに分割し、結果セットをマージします。これにより、インデックスの活用や並列処理によってパフォーマンスを向上させることができる場合があります。
OceanBaseデータベースは、コストモデルを使用してクエリ操作のリソース消費量を見積もります。このモデルは、一連の式と定数パラメータに基づいて演算子のコストを評価します。例えば、EXCHANGE IN 演算子のコストは以下の式で表されます:
cost = rows * row_width * NETWORK_TRANS_PER_BYTE_COST +
rows * row_width * NETWORK_DESER_PER_BYTE_COST
ここで、式には演算子の出力行数 rows とデータ幅 row_width の2つの要素が含まれ、ネットワーク転送コスト NETWORK_TRANS_PER_BYTE_COST とデータ逆シリアライズコスト NETWORK_DESER_PER_BYTE_COST を組み合わせて総コストを計算します。
OceanBaseデータベースの適応型コストモデルの鍵は、これらのコスト係数を特定のハードウェア環境に合わせて調整することにあります。データベースのインストール時に自動化スクリプトを使用して新しいコスト係数を計算することは可能ですが、オプティマイザーが使用するコスト係数が多すぎ、計算プロセスが複雑すぎるため、自動化スクリプトがあっても全体の計算プロセスが複雑すぎてエラーの可能性が高く、ユーザーエクスペリエンスが悪くなる可能性があります。
係数の適応的調整を簡素化するために、コストモデルの係数を以下の主要なハードウェアパラメータの関数に正規化することができます。現在使用されているコストモデル係数をこれら4つの基本係数の組み合わせに正規化することができます。
- CPU周波数(CPU_SPEED)
- ハードディスクの順次読み取り速度
- ハードディスクのランダム読み取り速度
- ネットワーク帯域幅
例えば、ハッシュテーブル探索のコスト係数はCPU命令数(CPU_CYCLES)に変換し、CPU周波数と組み合わせて現在の環境におけるハッシュテーブル探索のコストに変換できます:
PROBE_HASH_PER_ROW_COST = CPU_CYCLES * CPU_SPEED;
このような正規化手法により、コストモデルの係数を現在のハードウェアから分離し、異なるシステム統計情報を使用して変換することで、異なるハードウェア環境のコスト係数を得ることができます。
OceanBaseデータベースの現在のコストモデルは適応機能をサポートしており、リアルタイムのハードウェア性能に基づいて計画のコストを評価し、必要に応じて最適化戦略をカスタマイズするために、ユーザーがコスト係数を手動で調整できるインターフェースを提供しています。