ワイドテーブルには、数十から数百の列が含まれる場合があります。クエリでは、これらの列のうち一部のみを分析する必要があることがよくあります。列ストアインデックスを使用することで、これらのクエリを高速化できます。
背景情報
多くの SaaS 業務システムでは、テーブルに数十から数百の列が含まれることがあり、クエリに技術的な課題をもたらします。
一部のクエリでは数個の列を分析するだけで済みますが、行指向ストレージエンジンを使用すると、多くの無関係な列が読み取られます。これにより、システムの I/O 負荷が増加します。
クエリモードは固定されていません。数百の列をクエリする際に、複数のフィルター条件を使用できます。複合インデックスを構築する場合、事前にすべてのクエリシナリオを考慮する必要があります。クエリ条件が変更されると、複合インデックスは無効になります。
列ストアインデックスは、これら 2 つのシナリオに適しています。列ストアインデックスは列ベースであるため、1 つの列を読み取っても他の列には影響しません。また、列は独立しているため、複数のフィルター条件の順序が列ストアインデックスの有効性に影響することもありません。
結果
1 億行のデータセットと 4 の並列処理の次数で、列ストアインデックスを使用するクエリは、ネイティブ PostgreSQL の並列実行よりも 30 倍高速に実行されます。
クエリ | ネイティブ PostgreSQL での並列実行 | 列ストアインデックス |
Q1 | 243 s | 7.9 s |
操作手順
ステップ 1:環境の準備
クラスターのバージョンと構成が、次の要件を満たしていることを確認してください。
クラスターバージョン:
PostgreSQL 16 (マイナーエンジンバージョン 2.0.16.8.3.0 以降)
PostgreSQL 14 (マイナーエンジンバージョン 2.0.14.10.20.0 以降)
説明コンソールで、または
SHOW polardb_version;文を実行して、マイナーエンジンバージョン番号を表示できます。マイナーエンジンバージョンが要件を満たしていない場合は、マイナーエンジンバージョンをアップグレードする必要があります。ソーステーブルにはプライマリキーが必要です。列ストアインデックスを作成する際には、プライマリキー列を含める必要があります。
wal_levelパラメーターをlogicalに設定する必要があります。これにより、論理レプリケーションをサポートするために必要な情報が先行書き込みログ (WAL) に追加されます。説明コンソールで wal_level パラメーターを設定できます。このパラメーターを変更するとクラスターが再起動します。ビジネス運用を適切に計画し、注意して進めてください。
列ストアインデックス機能を有効にします。
列ストアインデックス機能を有効にする方法は、ご利用の PolarDB for PostgreSQL クラスターのマイナーエンジンバージョンによって異なります。
ステップ 2:データの準備
この例では、widecolumntable という名前のテーブルを使用します。このテーブルには、BIGINT、DECIMAL、TEXT、JSONB、TEXT[] などのデータ型の 24 列が含まれています。この例では、5 つの列 (id_1、domain、consumption、start_time、end_time) を分析して、過去 1 年間に各顧客が複数のドメインで費やした合計金額を計算します。
次のテーブルスキーマで
widecolumntableという名前のテーブルを作成します。次に、必要に応じてテストデータを挿入します。CREATE TABLE widecolumntable ( id_1 BIGINT NOT NULL PRIMARY KEY, id_2 BIGINT, id_3 BIGINT, id_4 BIGINT, id_5 BIGINT, id_6 BIGINT, version INT, domain TEXT, consumption DECIMAL(18,3), c_level CHARACTER varying(1) NOT NULL, priority BIGINT, operator TEXT, notify_policy TEXT, call_id UUID NOT NULL, provider_id BIGINT NOT NULL, name_1 TEXT NOT NULL, name_2 TEXT NOT NULL, name_3 TEXT, start_time TIMESTAMP WITH TIME ZONE NOT NULL, end_time TIMESTAMP WITH TIME ZONE NOT NULL, comment JSONB NOT NULL, description TEXT[] NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL );id_1、domain、consumption、start_time、end_timeの各列を列ストアインデックスに追加します。CREATE INDEX idx_wide_csi ON widecolumntable USING CSI(id_1, domain, consumption, start_time, end_time);
ステップ 3:クエリの実行
異なる実行エンジンを使用して、過去 1 年間に各顧客が異なるドメインで費やした合計金額を計算し、結果を合計金額でソートするクエリを実行します。
列ストアインデックスを使用します。
--- 列ストアインデックスを有効にし、並列処理の次数を 4 に設定します。 SET polar_csi.enable_query to on; SET polar_csi.exec_parallel to 4; ---Q1 EXPLAIN ANALYZE SELECT id_1, domain,SUM(consumption) FROM widecolumntable WHERE start_time > '20230101' and end_time < '20240101' GROUP BY id_1, domain Order By SUM(consumption);列ストアインデックスを無効にし、ローストアエンジンを使用します。
--- 列ストアインデックスを無効にし、ローストアエンジンを使用し、並列処理の次数を 4 に設定します。 SET polar_csi.enable_query to off; SET max_parallel_workers_per_gather to 4; ---Q1 EXPLAIN ANALYZE SELECT id_1, domain,SUM(consumption) FROM widecolumntable WHERE start_time > '20230101' and end_time < '20240101' GROUP BY id_1, domain Order By SUM(consumption);





