データベースにおけるクエリのリライト(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データベースの現在のコストモデルは適応機能をサポートしており、リアルタイムのハードウェア性能に基づいて計画のコストを評価し、必要に応じてユーザーがコスト係数を手動で調整できるインターフェースを提供しています。これにより、カスタムの最適化戦略を設定できます。