データベースにおけるクエリリライト(Query Rewrite)とは、あるSQL文をより最適化しやすい別のSQL文に変換することを指します。
OceanBaseデータベースでは、ルールに基づくリライトとコストに基づくリライトという2種類のクエリリライトルールが提供されています。
ルールに基づくクエリリライト は常にSQL文を「より良い」方向へと変換し、その結果、そのSQL文の最適化の余地を拡大します。例えば、サブクエリを結合演算に変換することは、典型的なルールに基づくリライトであり、これによりオプティマイザーが考慮する実行計画が拡張され、Hash JoinやMerge Joinなどの代替案が可能になり、Nested Loop 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データベースの現在のコストモデルは、V4.3.0バージョンから適応機能をサポートしており、リアルタイムのハードウェア性能に基づいて計画のオーバーヘッドを評価し、必要に応じてユーザーがコスト係数を手動で調整できるインターフェースを提供しています。これにより、ユーザーは必要に応じて最適化戦略をカスタマイズできます。