PolarDB for MySQL のインメモリ列指向インデックス (IMCI) は、低速 SQL クエリのパフォーマンスを自動的に向上させる機能「IMCI ベースの自動クエリ高速化」を提供します。
概要
PolarDB for MySQL のインメモリ列指向インデックス (IMCI) 機能は、OLAP シナリオの大規模なデータセットに対する複雑なクエリ向けに特別に設計されています。 IMCI により、PolarDB for MySQL はリアルタイムのトランザクション処理とリアルタイムのデータ分析のための統合機能を提供することで、ワンストップの HTAP データベースソリューションを実現します。
従来の方法では、低速クエリに関連するテーブルを高速化するには、CREATE TABLE または ALTER TABLE を使用して、テーブルの COMMENT フィールドに COLUMNAR=1 を追加することで、手動で列指向インデックスを作成する必要があります。 この手動の方法は、複雑なロジックを持つ SQL テンプレートが多数ある場合には非効率です。
IMCI ベースの自動クエリ高速化 (AutoIndex) 機能は、低速クエリに基づいてテーブルに列指向インデックスを追加することで、このプロセスを自動化します。
技術的背景
AutoIndex は、インデックスを自動的に追加することによって SQL のパフォーマンスをチューニングする手法です。 行ストアインデックスの場合、この概念は十分に研究されており、Oracle や SQL Server などのシステムで商用実装されています。 これらのシステムは通常、述語、ORDER BY 句、または JOIN 操作を分析して、潜在的なセカンダリインデックスを特定します。 次に、インデックスが作成されたと仮定してクエリコストを再計算し、コストを大幅に削減するインデックスを作成します。
列指向インデックスの場合、AutoIndex は Redshift、Snowflake、Databricks、Heatwave などのシステムで採用されています。 一般的な自動化技術には、次のものがあります:
自動ロードおよびアンロード:クエリの実行履歴に基づいて低速クエリを高速化するために、列指向インデックスを自動的に作成します。 使用頻度が低い、またはリソースを大量に消費する列指向インデックスは自動的に削除され、ストレージ消費量を削減します。
自動エンコーディング:各列のデータ分布に基づいて最適なエンコーディングアルゴリズムを自動的に選択し、ストレージ領域をさらに圧縮します。
ディストリビューションキーの自動選択:超並列処理 (MPP) シナリオでデータ分散のバランスを取り、データスキューを削減し、分散 GROUP BY および JOIN 操作のデータシャッフルを最適化します。
ソートキーの自動選択:結合やソートに関与する一般的な述語や列を使用して、クエリのフィルタリングやソートを高速化します。
IMCI で列指向インデックスを自動的に作成することは、以下の理由により、行ストアインデックスを作成するよりもコストが低く、耐障害性に優れています:
書き込みへの影響が少ない:行ストアインデックスが多すぎると、プライマリノードでの書き込みパフォーマンスが大幅に低下する可能性があります。 対照的に、IMCI はプライマリノードに列ストアデータをマテリアライズしません。 新しい列指向インデックスが追加されると、書き込み操作は REDO ログを介して読み取り専用 IMCI ノードに同期されるため、書き込みパフォーマンスへの影響は最小限です。
高い圧縮率:列指向インデックスは通常 3 倍から 5 倍の圧縮率を達成できるため、新しいインデックスを追加することによるストレージオーバーヘッドは比較的小さくなります。
ビジネスオペレーションへの限定的な影響:システムはロックフリーで効率的なデータ構造を使用して SQL トレース情報を収集し、非ブロッキング DDL を採用してビジネスオペレーションへの支障を最小限に抑えます。
仕組み
低速クエリの追跡と DDL 文の生成
クラスター内の各ノードは SQL Trace 機能を使用して低速クエリを収集し、これらのクエリ用の列指向インデックスを作成するための DDL 文を自動的に生成します。 プロセスは以下のとおりです:
SQL Trace:システムは公式の MySQL ロックフリーハッシュテーブルを使用して、SQL テンプレートをキーとして SQL の実行情報を追跡および記録します。 このアプローチは、高い同時実行性と多数の SQL テンプレートを持つシナリオに適しています。 Sysbench テストシナリオでは、SQL Trace のパフォーマンスへの影響は 3% 以下です。
トリガー条件:低速クエリによってスキャンされた行数が設定されたしきい値に達すると、AutoIndex は対応するテーブルに列指向インデックスを追加するための DDL 文を生成します。
低オーバーヘッド設計:繰り返し発生する SQL 解析、テーブルのオープン、メタデータロック (MDL) の取得を回避するため、AutoIndex はスレッドハンドラー (THD) からキャッシュされたテーブルリストを直接使用し、システムに追加の負担をほとんどかけません。
各ノードに直接接続し、information_schema.imci_autoindex システムテーブルをクエリすることで、追跡された低速クエリとその生成された DDL 文のセットに関する情報を表示できます。 例:
SELECT * FROM information_schema.imci_autoindexinformation_schema.sql_sharing を使用すると、より詳細な SQL 実行情報を取得できます:
SELECT *
FROM information_schema.imci_autoindex autoindex, information_schema.sql_sharing share
WHERE autoindex.sql_id = share.sql_id
AND share.type = 'SQL'低速クエリの収集、集計、および DDL の実行
クラスター内に複数の読み取り専用 IMCI ノードが存在する場合、そのうちの 1 つがリーダーとして機能し、すべてのノードから低速クエリの推奨事項を収集して集計します。 このリーダーノードは、実行時間に基づいて降順で推奨事項をソートし、ラウンドごとの DDL 実行しきい値に達するまで、推奨される DDL 文を順次実行します。
Instant DDL
プライマリノードでは、列指向インデックスの追加は Instant DDL 操作です。 データディクショナリのみを更新し、プライマリノードのデータは変更しません。 対応する REDO ログが読み取り専用 IMCI ノードに複製されると、バックグラウンドで列指向インデックスが構築されます。
非ブロッキング DDL
標準の DDL 操作は、MDL-X ロックの取得を待つ間、新しいトランザクションをブロックします。 対照的に、非ブロッキング DDL は、ロックの取得に失敗した場合でも新しいトランザクションの続行を許可し、その後ロックの取得を再試行し続けます。 AutoIndex 機能では、DDL 操作に緊急性はありません。 現在のラウンドで DDL が失敗した場合、システムは後続の自動スケジューリングラウンドで再試行できます。
クラスターエンドポイントから information_schema.imci_autoindex_executed システムテーブルをクエリすると、最近成功した列指向インデックスの推奨文と関連する低速クエリを表示できます (最大 128 レコードが保持されます)。
スケジューリングと実行の制限
デフォルトでは、ラウンド間の間隔は 1 分で、ラウンドごとに最大 5 件の DDL 文が実行されます。
現在のラウンドで実行されなかった列指向インデックス作成の推奨は、対応する低速クエリが再度検出された後にのみ再試行されます。
読み取り専用 IMCI ノードが列指向インデックスを構築する際には、リソースガバナンスが適用されます。 リソース使用率は上昇しますが、ノードのリソースが飽和することはありません。
次のラウンドは、現在のラウンドのすべての列指向インデックスの構築が読み取り専用 IMCI ノードで完了した後にのみスケジュールされます。
列指向インデックスのアクティブ化と使用
AutoIndex の効果を最大化するには、読み取り専用 IMCI ノードをクラスターエンドポイントにアタッチし、自動行/列ルーティングを有効にすることを推奨します。 実際のワークロードのリプレイ中に、低速クエリが AutoIndex をトリガーして列指向インデックスを作成します。 読み取り専用 IMCI ノードがインデックスの構築を完了すると、自動ルーティングメカニズムはクエリコストに基づいて関連クエリを読み取り専用 IMCI ノードに転送することでクエリを高速化します。
アプリケーションのトラフィックが通常の読み取り専用ノードに直接接続している場合、列指向インデックスの作成後に手動でトラフィックを読み取り専用 IMCI ノードに切り替えることができます。 列指向インデックスのステータスとルーティングポリシーのクエリに関する詳細については、「IMCI FAQ」をご参照ください。
テスト結果
以下は、TPC-H 100 GB テストスイートに基づく例です。
本トピックで説明する TPC-H の実装は TPC-H ベンチマークに基づいていますが、TPC-H のすべての要件に準拠しているわけではありません。 本トピックのテスト結果は、公開されている TPC-H ベンチマークの結果とは比較できません。
環境設定:22 の TPC-H テストクエリすべてを 1 分に 1 回実行します。 クラスターエンドポイントで HTAP の最適化 (トランザクションと分析処理の分離) を有効にします。 行ストアの並列度を 8 に設定します (主にテスト時間を短縮するため)。
テスト結果:以下の表に示すように、後続のラウンドでのクエリパフォーマンスは大幅に向上しました。 最初のラウンドの終わり頃 (12 番目のクエリあたりから)、AutoIndex はすでにほとんどのテーブルに対して列指向インデックスを作成しており、オプティマイザはこれらのクエリを自動的に読み取り専用 IMCI ノードにルーティングしました。
実行ラウンド | 合計時間 (秒) | 行/列プラン | パフォーマンス向上 |
1 | 8,293 | 10 / 12 | - |
2 | 118 | 1 / 21 | 約 70 倍 |
3 | 110 | 0 / 22 | 約 75 倍 |
メリット
IMCI 機能は、互換性、パフォーマンス、およびコスト効率の面で大きなメリットがあります:
完全な MySQL 互換性:すべての MySQL データ型と MySQL プロトコルをサポートします。
優れた HTAP パフォーマンス:分析ワークロードに対して 1~2 桁のパフォーマンス向上を実現します。
コスト効率の高いハイブリッドストレージ:ハイブリッドストレージはトランザクションの一貫性を保証し、列指向インデックスは特定のクエリシナリオで優れたパフォーマンスと低コストを提供します。
ワンクリック自動高速化:ワンクリックで自動的にパフォーマンスを向上させ、複雑な設定やチューニングは不要です。
運用オーバーヘッドの削減:低速クエリに対して列指向インデックスを自動的に作成し、手動での最適化作業を最小限に抑えます。
IT コストの削減:すべてのデータベースやテーブルではなく、低速クエリに対してのみ列指向インデックスを作成することで、メモリとストレージリソースを節約します。
サポートされるバージョン
Enterprise Edition クラスターは、次の条件を満たす必要があります:
シリーズ:Cluster Edition。
データベースエンジンバージョン:
MySQL 8.0.1、リビジョン 8.0.1.1.45.2 以降。
MySQL 8.0.2、リビジョン 8.0.2.2.27 以降。
Standard Edition クラスターは、次の条件を満たす必要があります:
CPU アーキテクチャ:X86。
データベースエンジンバージョン:MySQL 8.0.1、リビジョン 8.0.1.1.45.2 以降。
クラスターのバージョンを確認するには、「エンジンバージョンの照会」をご参照ください。
注意事項
Multi-master Cluster (Limitless) Edition および Serverless クラスターは、IMCI ベースの自動クエリ高速化をサポートしていません。
IMCI ベースの自動クエリ高速化を有効にすると、次のようになります:
IMCI ベースの自動クエリ高速化機能は、非ブロッキング DDL を使用して列指向インデックスを追加します。 非ブロッキング DDL 機能は、MDL-X ロックが取得できない場合でも新しいトランザクションがターゲットテーブルにアクセスできるようにすることで、アプリケーションの安定性を維持します。 詳細については、「非ブロッキング DDL」をご参照ください。
IMCI ベースの自動クエリ高速化の有効化
PolarDB コンソール にログインします。 左側のナビゲーションペインで クラスター をクリックし、クラスターが存在する [リージョン] を選択して、対象クラスターの ID をクリックし、クラスターの詳細ページに移動します。
基本情報 ページで 自動列ストアインデックスによる高速化 フィールドを見つけ、有効 をクリックします。
以降の手順は、クラスターにすでに読み取り専用 IMCI ノードがあるかどうかによって異なります:
クラスターにすでに読み取り専用 IMCI ノードがある場合は、列ストアインデックスの自動高速化の有効化 ダイアログボックスで OK をクリックして機能を有効にします。
クラスターに読み取り専用 IMCI ノードがない場合は、列ストアインデックスの自動高速化の有効化 ダイアログボックスで OK をクリックします。 読み取り専用 IMCI ノードを追加するページにリダイレクトされます。
説明OK をクリックした直後に 読み取り専用 IMCI ノードを追加することも、後で手動で読み取り専用 IMCI ノードを追加することもできます。
この機能を有効にした後、クラスターには少なくとも 1 つの読み取り専用 IMCI ノードが存在する必要があります。 そうでない場合、自動列ストアインデックスによる高速化 のステータスが 有効 であっても、クエリの高速化は有効になりません。
この機能を有効にしても読み取り専用 IMCI ノードを追加しない場合、システムはSQL Trace を使用して低速 SQL クエリの実行履歴を記録しますが、列指向インデックスは作成しません。 その結果、高速化は行われません。
IMCI ベースの自動クエリ高速化の無効化
PolarDB コンソール にログインし、左側のナビゲーションペインで クラスター をクリックし、クラスターが存在する [リージョン] を選択して、対象クラスターの ID をクリックし、クラスターの詳細ページに移動します。
基本情報 ページで、自動列ストアインデックスによる高速化 フィールドを見つけ、シャットダウン をクリックします。
列ストアインデックスの自動高速化の無効化 ダイアログボックスで、OK をクリックして機能を無効にします。
IMCI ベースの自動クエリ高速化を無効にしても、機能が無効になるだけで、既存の読み取り専用 IMCI ノードやそのデータは削除されません。 不要になった場合は、コンソールで読み取り専用 IMCI ノードを削除するか、DDL 文を使用して列指向インデックスを削除することができます。