PolarDB for PostgreSQL は、大規模データセットに対する分析クエリを高速化するための列ストアインデックス (CSI) をサポートしています。クラスターバージョンに応じて、専用のインメモリー列指向インデックス (IMCI) 読み取り専用ノードを追加するか、または組み込みの polar_csi 拡張を直接使用して CSI を有効化できます。
前提条件
作業を開始する前に、以下の条件を満たしていることを確認してください。
ご利用のクラスターがサポート対象バージョンを実行していること:マイナーエンジンバージョンを確認するには、
SHOW polardb_version;を実行するか、コンソールで確認します。バージョン要件を満たしていない場合は、まずマイナーエンジンバージョンをアップグレードしてください。PostgreSQL 16(マイナーエンジンバージョン 2.0.16.8.3.0 以降)
PostgreSQL 14(マイナーエンジンバージョン 2.0.14.10.20.0 以降)
wal_levelパラメーターがlogicalに設定されていること。これにより、先行書き込みログ (WAL) で論理レプリケーションがサポートされます。説明コンソールで
wal_levelパラメーターを変更すると、クラスターが再起動されます。メンテナンスウィンドウを適切に計画してください。インデックスを作成する各テーブルにプライマリキーが設定されており、そのプライマリキー列が列ストアインデックスに含まれていること。
制限事項
各テーブルでは、1 つの列ストアインデックスのみをサポートします。
既存の列ストアインデックスを変更することはできません。列を追加するには、インデックスを削除して再作成する必要があります。
列ストアインデックス機能の有効化
有効化方法の選択
利用可能な方法は、マイナーエンジンバージョンによって異なります。
PostgreSQL 16(2.0.16.9.8.0 以降)または PostgreSQL 14(2.0.14.17.35.0 以降)の場合
次の 2 つの方法が利用可能です。ワークロードの隔離要件およびコスト要件に基づいて選択してください。
| IMCI 読み取り専用ノードの追加(推奨) | プリインストール済み拡張の使用 | |
|---|---|---|
| セットアップ | コンソールからノードを追加 | セットアップ不要。拡張はプリインストール済み |
| メモリ | 列ストアエンジンがノードの全メモリを専有 | 列ストアエンジンはノードメモリの 25% に制限 |
| ワークロードの隔離 | トランザクション処理 (TP) と分析処理 (AP) のワークロードが別々のノードで実行 | TP および AP ワークロードが同一ノードを共有 |
| コスト | 追加料金が発生し、通常のコンピュートノード | 追加コストなし |
PostgreSQL 16(2.0.16.8.3.0 ~ 2.0.16.9.8.0)または PostgreSQL 14(2.0.14.10.20.0 ~ 2.0.14.17.35.0)の場合
1 つの方法のみが利用可能で、polar_csi 拡張を手動でインストールする必要があります。polar_csi 拡張のインストールをご参照ください。
IMCI 読み取り専用ノードの追加
クラスター購入時または稼働後に IMCI 読み取り専用ノードを追加できます。
IMCI ノードを追加するには、クラスターに少なくとも 1 つの読み取り専用ノードが存在している必要があります。シングルノードクラスターはサポートされていません。
購入時の追加
PolarDB 購入ページで、IMCI 読み取り専用ノード パラメーターのノード数を設定します。

コンソールでの追加
PolarDB コンソールにログインし、ご利用のクラスターが配置されているリージョンに移動します。ノードの追加/削除 ウィザードを次のいずれかの方法で開きます。
クラスター ページで、操作 列の ノードの追加/削除 をクリックします。

ご利用のクラスターの 基本情報 ページで、データベースノード セクションの ノードの追加/削除 をクリックします。

読み取り専用 IMCI ノードの追加 を選択し、OK をクリックします。
スペックアップ/ダウンページでノードを構成および購入します:

IMCI ノードの追加 をクリックし、ノードスペックを選択します。
スイッチオーバーのタイミングを選択します。
(任意)プロダクト利用規約およびサービスレベル契約を確認します。
今すぐ購入 をクリックします。
クラスター詳細ページに戻り、ノードステータスが 実行中 に変化するまで待ちます。

polar_csi 拡張のインストール
拡張をインストールするために使用するデータベースアカウントは、特権アカウントである必要があります。
polar_csi 拡張はデータベースレベルでスコープが設定されます。クラスター内の複数のデータベースで CSI を使用するには、各データベースに個別に拡張をインストールする必要があります。
この方法は、PostgreSQL 16(2.0.16.8.3.0 ~ 2.0.16.9.8.0)または PostgreSQL 14(2.0.14.10.20.0 ~ 2.0.14.17.35.0)を実行しているクラスター向けです。それ以降のバージョンでは、拡張はプリインストール済みです。
コンソールからのインストール
PolarDB コンソールにログインし、クラスター ID をクリックしてクラスター詳細ページに移動します。
左側のナビゲーションウィンドウで、設定と管理 > 拡張機能管理 を選択します。
拡張機能管理 タブで、未インストールの拡張機能 を選択します。
右上隅で対象のデータベースを選択し、polar_csi 行の インストール をクリックします。ダイアログボックスで対象の データベースアカウント を選択し、OK をクリックします。

コマンドラインからのインストール
データベースクラスターに接続し、対象のデータベースで次の文を実行します。
CREATE EXTENSION polar_csi;列ストアインデックスの作成
構文
列ストアインデックスを作成するには、USING CSI 句を使用します。インデックス作成中に書き込み操作をブロックしないようにするには、CONCURRENTLY を含めてください。
-- 特定の列をインデックス化
CREATE INDEX [ CONCURRENTLY ] <index_name> ON <table_name> USING CSI(<column1>, <column2>, ...);
-- すべての列をインデックス化
CREATE INDEX [ CONCURRENTLY ] <index_name> ON <table_name> USING CSI;パラメーター
| パラメーター | 説明 |
|---|---|
CONCURRENTLY | 省略可能。ソーステーブルへの書き込み操作をブロックせずにインデックスを作成します。オンライン中の既存テーブルに使用してください。バージョン要件については、下記の注を参照してください。 |
<index_name> | 列ストアインデックスの名前。 |
<table_name> | インデックスを作成するテーブルの名前。 |
<column1>, <column2>, ... | インデックスに含める列。省略した場合、すべての列がインデックス化されます。 |
CONCURRENTLYには、PostgreSQL 14 でマイナーエンジンバージョン 2.0.14.13.27.0 以降が必要です。このバージョンでは、論理レプリケーションスロット機能がデフォルトで有効になります。古いバージョンでは、polar_csi拡張を再インストールするか、サポートにお問い合わせください。同時インデックス作成中は、一時的な論理レプリケーションスロットが作成され、データ同期完了後に自動的に解放されます。
例
プライマリキーを持つテストテーブルを作成します。
CREATE TABLE sales (sale_id int primary key, name CHAR(10), amount int);列ストアインデックスを作成します。次のいずれかのオプションを選択してください。
目的 文 特定の列をインデックス化 CREATE INDEX idx_csi_sales ON sales USING CSI(sale_id, amount);すべての列をインデックス化 CREATE INDEX idx_csi_sales ON sales USING CSI;書き込みをブロックせずに特定の列をインデックス化 CREATE INDEX CONCURRENTLY idx_csi_sales ON sales USING CSI(sale_id, amount);インデックスが作成されたことを確認します。
SELECT * FROM pg_indexes WHERE tablename = 'sales';
インデックス作成の進捗状況の監視
大規模なテーブルの場合、インデックス作成には相当な時間がかかることがあります。次のコマンドで進捗状況を確認できます。
SELECT * FROM pg_stat_progress_create_index;監視すべき主な列は次のとおりです。
| 列 | 何を示すか |
|---|---|
phase | インデックス作成の現在のフェーズ(例:building index) |
blocks_done / blocks_total | テーブル全体に対する処理の進捗 |
tuples_done / tuples_total | これまでに処理された行数 |
blocks_done が blocks_total に等しく、かつ tuples_done が tuples_total に等しい場合、インデックス作成は完了しています。
インデックス作成のキャンセル
インデックス作成に時間がかかりすぎてワークロードに影響を及ぼす場合は、pg_stat_progress_create_index から取得したプロセス ID (pid) を使用してキャンセルできます。
-- グレースフルにキャンセル
SELECT pg_cancel_backend(<pid>);
-- 強制終了
SELECT pg_terminate_backend(<pid>);インデックスサイズの確認
SELECT pg_size_pretty(pg_relation_size('idx_csi_sales'));リアルタイムデータ同期の構成
列ストアインデックスを作成後、ローストアテーブルに書き込まれた新しいデータは、リアルタイムでインデックスに自動的に同期されます。追加の構成は不要です。
書き込み量が多いシナリオ(PostgreSQL 14、マイナーエンジンバージョン 2.0.14.13.28.0 以降)で同期パフォーマンスを調整するには、次のパラメーターを変更します。
| パラメーター | 範囲 | デフォルト | 効果 |
|---|---|---|---|
polar_csi.update_interval | 0~3,600 秒 | 3 秒 | 同期間隔。この値を増やすと、小規模なトランザクションがバッチ処理され、書き込み量が多い場合のスループットが向上します。 |
polar_csi.update_batch_count | 1,024~4,294,967,295 | 100,000 | 1 回のバッチ更新あたりの最大行数。この値を増やすと、大規模トランザクションの更新効率が向上します。 |
これらのパラメーターは、PostgreSQL 14(マイナーエンジンバージョン 2.0.14.13.28.0 以降)でのみ使用可能です。PostgreSQL 16 には同等のパラメーターはありません。
列ストアインデックスの使用
クエリルーティングの有効化
デフォルトでは、クエリは列ストアインデックスを使用しません。ユースケースに合わせて、次のスコープで有効化してください。
グローバルスコープ
(すべてのデータベース、すべてのセッション)
セッションスコープ
(現在のセッションのみ)
SET polar_csi.enable_query = ON;クエリ単位のスコープ
(単一の文)
これには pg_hint_plan 拡張が必要です。まずインストールしてください。
CREATE EXTENSION pg_hint_plan;その後、クエリ内にヒントコメントを使用します。
-- 単一のクエリを列ストアインデックスにルーティング
/*+ SET(polar_csi.enable_query on) */ SELECT COUNT(*) FROM sales;
-- 単一のクエリをルーティングし、コストのしきい値を設定
/*+ SET(polar_csi.enable_query on) SET(polar_csi.cost_threshold 0) */ SELECT COUNT(*) FROM sales;コストのしきい値の制御
polar_csi.cost_threshold パラメーターは、列ストアエンジンを使用するタイミングを決定します。クエリコストの推定値がしきい値を下回る場合はローストアエンジンがクエリを処理し、上回る場合は列ストアエンジンが処理します。
SET polar_csi.cost_threshold = 0;polar_csi.cost_thresholdを0に設定すると、ローストアの方がパフォーマンスが良い可能性のあるシンプルな検索を含め、すべてのクエリが列ストアインデックスを使用するよう強制されます。本番環境ではこの設定を避けてください。実際のワークロードに基づいてしきい値を調整してください。
クエリが列ストアインデックスを使用していることの確認
EXPLAIN を使用してクエリプランを確認します。列ストアインデックスを使用しているクエリでは、プラン出力に CSI Executor が表示されます。
SHOW polar_csi.cost_threshold;
EXPLAIN SELECT COUNT(*) FROM sales;期待される出力:
QUERY PLAN
--------------
CSI Executor
(1 row)CSI Executor が表示されない場合は、トラブルシューティングをご参照ください。
クエリ整合性の構成
列ストアインデックスは、次の 2 種類の整合性レベルをサポートしています。
| レベル | パラメーター値 | 動作 | 使用タイミング |
|---|---|---|---|
| 結果整合性(デフォルト) | polar_csi.forward_replay_wait = off | 書き込み処理中にクエリがやや古いデータを返す可能性がある | ニアリアルタイムのデータで問題ない高書き込みワークロード |
| 強力な整合性 | polar_csi.forward_replay_wait = on | クエリが結果を返す前に、列ストアデータがローストアと同期されるまで待機 | 最新の書き込みを反映する必要があるクエリ |
-- 強力な整合性を有効化
SET polar_csi.forward_replay_wait = on;書き込み負荷が高い場合、強力な整合性によりクエリの待機時間が長くなる可能性があります。ユースケースで必要となる場合にのみ有効化してください。
列ストアインデックスの削除と再構築
列ストアインデックスは、その場で変更できません。列を追加または削除するには、インデックスを削除して再作成するか、再構築してください。
列ストアインデックスの削除
DROP INDEX idx_csi_sales;列ストアインデックスの再構築
REINDEX INDEX idx_csi_sales;パフォーマンスチューニング
インデックス作成の高速化
| パラメーター | 範囲 | デフォルト | 説明 |
|---|---|---|---|
polar_csi.memory_limit | 1~1,048,576 MB | 1,024 MB | 列ストアエンジンが利用可能なメモリ量。値を大きくするとインデックス作成が高速化されます。メモリ不足 (OOM) エラーを回避するため、クラスターメモリ総量の 20% 以下に維持してください。 |
polar_csi.flush_count | 2,048~20,480,000 | 204,800 | 1 回のバッチコミットあたりの行数。この値を増やすとスループットが向上しますが、より多くのメモリを必要とします。 |
クエリの高速化
| パラメーター | 範囲 | デフォルト | 説明 |
|---|---|---|---|
polar_csi.exec_parallel | 1~512 | 2 | クエリあたりの並列度。値を大きくすると、大規模データセットをスキャンするクエリのパフォーマンスが向上します。コンピュートノードの CPU コア数以下に維持してください。 |
polar_csi.memory_limit | 1~1,048,576 MB | 1,024 MB | 列ストアエンジンが利用可能なメモリ量。メモリ不足 (OOM) エラーを回避するため、クラスターメモリ総量の 20% 以下に維持してください。 |
polar_csi.cost_threshold | 1~1,000,000,000 | 50,000 (PG14);1,000 (PG16) | 列ストアルーティングのクエリコストしきい値。値が非常に大きいと複雑なクエリがインデックスを使用しなくなる可能性があり、逆に非常に小さいとシンプルなクエリが列ストアにルーティングされ、同時実行数が低下する可能性があります。ワークロードに基づいて調整してください。 |
polar_csi.forward_replay_wait | on | off | off | 整合性レベル。off = 結果整合性;on = 強力な整合性(クエリが同期を待機)。 |
PostgreSQL 14 では、polar_csi.cost_threshold のデフォルト値が、マイナーエンジンバージョン 2.0.14.13.28.0 で 50,000 に変更されました。それ以前のバージョンでは、デフォルト値は 1,000 です。トラブルシューティング
クエリが列ストアインデックスを使用していない
EXPLAIN 出力に CSI Executor が表示されない場合は、次のチェックを順に実施してください。
`polar_csi.enable_query` が on になっていることを確認します。
SHOW polar_csi.enable_query;出力が
offの場合は、次のように有効化します。SET polar_csi.enable_query = ON;コストのしきい値を確認します。
SHOW polar_csi.cost_threshold; EXPLAIN SELECT COUNT(*) FROM sales;クエリの推定コスト(
EXPLAIN出力)をしきい値と比較します。コストがしきい値より低い場合、設計上ローストアエンジンがクエリを処理します。しきい値を下げてテスト用に列ストアルーティングを強制するか、クエリ単位のヒントを使用してください。列ストアインデックスがクエリで参照される列をカバーしていることを確認します。
SELECT * FROM pg_indexes WHERE tablename = 'sales';インデックスにクエリで参照される列が含まれていない場合は、正しい列を指定してインデックスを削除・再作成してください。
サポートされていない機能がないか確認します。 制限事項を確認し、クエリおよびテーブル構成がすべての要件を満たしていることを確認してください。