すべてのプロダクト
Search
ドキュメントセンター

Hologres:インデックスの概要

最終更新日:Mar 11, 2026

本トピックでは、Hologres の主要なインデックス(分散キー、イベント時刻列(セグメントキー)、クラスタリングキー)について説明し、Hologres 開発時のクエリパフォーマンス向上を支援します。

Hologres 分散データウェアハウスの基本原理

Hologres は分散型データウェアハウスです。並列計算およびベクター計算を活用して、数秒以内のクエリ応答を実現します。そのため、データ分布の特性はパフォーマンスにとって極めて重要です。これらの特性には、複数の分散ノードにわたる均等なデータ分布(distribution_key)と、単一ノード内のファイルにおけるデータの順序付き分布(event_time_column/segment_key)が含まれます。Hologres は、オンライン分析処理(OLAP)シナリオ向けにデフォルトでカラムストア形式を採用しています。このため、ファイル内におけるデータの順序付き分布(clustering_key)も非常に重要となります。これらの 3 つの概念を理解することで、パフォーマンスを大幅に向上させることができます。データ分布の特性はデータ書き込み時に決定され、後から調整するにはコストがかかります。したがって、テーブル作成時にデータレイアウトに関連するこれら 3 つのプロパティを設計する必要があります。データレイアウトとは直接関係しないプロパティ(ビットマップ索引(bitmap_columns)や辞書エンコーディング(dictionary_columns)など)は、テーブル作成後に必要に応じて調整可能です。

Hologres はまた、データベース > スキーマ > テーブルの 3 段階メタデータ構造を採用しています。論理的に関連するテーブルは同一スキーマ内に配置し、クロスデータベースクエリを回避してください。データベースは、リソース隔離ではなく、メタデータ隔離の基本単位です。

SQL 最適化の基本原則:I/O の削減と同時実行数の最適化

テーブル作成時に適切なデータ分布を設計することで、SQL 実行時にデータを迅速に特定できます。これにより I/O 消費が削減され、少ないコンピューティングリソースでより高いクエリパフォーマンスを実現できます。また、均等なデータ分布は、同時実行リソースを十分に活用し、単一ポイントのボトルネックを回避します。以下の図は、SQL クエリの実行フロー(開始からデータ取得まで)を示しています。この図を参照して、I/O を削減する方法をご確認ください。image

  • パーティションプルーニング:パーティションテーブルに対する SQL クエリ実行時には、必要なパーティションを特定するためにパーティションプルーニングが使用されます。クエリにパーティションキーに対するフィルター条件が含まれていない場合、すべてのパーティションを走査する必要があります。これにより過剰な I/O スキャンが発生します。通常、パーティションの粒度として「日単位」が適切です。非パーティション化テーブルでは、このステップはスキップされます。

  • シャードプルーニング:分散キー(distribution_key)を使用して、データを含むデータシャードを迅速に特定します。これにより、単一 SQL クエリのリソース消費を削減し、同時実行 SQL クエリのスループットを向上させます。特定のシャードを特定できない場合、分散フレームワークはすべてのシャードを計算に参加させます。これにより、単一 SQL クエリの並列処理の次数が増加し、より多くのリソースが使用されるため、全体の同時実行数が低下します。また、集中実行を必要とする一部の演算子は、追加のシャッフリングオーバーヘッドを引き起こします。通常、注文 ID、ユーザー ID、イベント ID のような均等な分布を持つフィールドを分散キーとして選択することを推奨します。結合が必要な複数のテーブルで同一の分散キーを設定すると、関連するデータが同一シャードに分散されます。これにより、ローカル JOIN を実行でき、JOIN 効率が向上します。

  • セグメントキー プルーニング:セグメントキー(event_time_column/segment_key)を使用して、単一ノード上の複数のファイルからデータを含むファイルを迅速に特定します。これにより、不要なファイルのオープンを回避できます。フィルタリングが不可能な場合、ノード上のすべてのファイルを走査する必要があります。

  • クラスタリングキー プルーニング:クラスタリングキー(clustering_key)を使用して、単一ファイル内のデータセグメントを迅速に特定します。これにより、範囲クエリおよびフィールドソートの効率が向上します。

SQL 最適化の実践例

本セクションでは、TPC-H クエリを例として、Hologres インデックスを設定してクエリパフォーマンスを向上させる方法を説明します。TPC-H の詳細については、「テスト計画の概要」をご参照ください。

TPC-H SQL の参考実践例

TPC-H Q1 クエリ

TPC-H Q1 は、lineitem テーブルの特定の列に対して集計およびフィルタリングを行います。

l_shipdate <=:クエリのフィルタリング条件です。範囲フィルタリングをサポートし、データフィルタリングを高速化するために、インデックスを設定する必要があります。

--TPC-H Q1
SELECT
        l_returnflag,
        l_linestatus,
        SUM(l_quantity) AS sum_qty,
        SUM(l_extendedprice) AS sum_base_price,
        SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
        SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
        AVG(l_quantity) AS avg_qty,
        AVG(l_extendedprice) AS avg_price,
        AVG(l_discount) AS avg_disc,
        COUNT(*) AS count_order
FROM
        lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus
ORDER BY
        l_returnflag,
        l_linestatus;

TPC-H Q4 クエリ

TPC-H Q4 は、主に lineitem テーブルと orders テーブルの結合クエリを実行します。

  • o_orderdate >= DATE '1996-07-01':フィルタリング条件です。範囲フィルタリングをサポートし、必要なデータを迅速に特定するために、インデックスを設定できます。

  • l_orderkey = o_orderkey:2 つのテーブル間の結合条件です。両テーブルで同一のインデックスを設定できます。2 つのテーブル間のインタラクション時にデータシャッフリング操作を削減するため、ローカル JOIN を実行することを推奨します。

    --TPC-H Q4 Query
    SELECT
            o_orderpriority,
            COUNT(*) AS order_count
    FROM
            orders
    WHERE
            o_orderdate >= DATE '1996-07-01'
            AND o_orderdate < DATE '1996-07-01' + INTERVAL '3' MONTH
            AND EXISTS (
                    SELECT
                            *
                    FROM
                            lineitem
                    WHERE
                            l_orderkey = o_orderkey
                            AND l_commitdate < l_receiptdate
            )
    GROUP BY
            o_orderpriority
    ORDER BY
            o_orderpriority;

テーブル作成に関する推奨事項

Q1 および Q4 クエリでは、lineitem テーブルおよび orders テーブルが使用されます。

hologres_dataset_tpch_100g.lineitem

Q1 および Q4 の両クエリで lineitem テーブルが使用されますが、使用されるフィールドおよびクエリ条件は異なります。

  • Q1 クエリの場合:クエリでは主に l_shipdate を使用して範囲フィルタリングを行います。クラスタリングキー(clustering_key)は、ファイル内のデータの順序を利用して範囲フィルタリングを高速化します。したがって、l_shipdate をクラスタリングキーとして設定できます。 セグメントキー(event_time_column)は、ファイル間の順序を維持するために使用されます。単調増加または単調減少する日付フィールドについては、セグメントキーとしても設定することを推奨します。これにより、ファイルレベルでの効果的なフィルタリングが可能になります。したがって、l_shipdate をセグメントキーとしても設定できます。

  • Q4 クエリの場合:クエリでは、lineitem テーブルの l_orderkey フィールドを用いて、orders テーブルの o_orderkey フィールドと結合します。分散キー(distribution_key)は、データ分布ポリシーを指定します。システムは、同一の distribution_key 値を持つデータを同一シャード上に格納します。2 つのテーブルが同一テーブルグループに属し、その結合フィールドが分散キーである場合、データ書き込み時に、両テーブルの同一キー値を持つレコードが自動的に同一シャードに分散されます。これらのテーブルを結合する際には、現在のノード上でローカル JOIN が実行されます。これにより、実行時に結合キーに基づくデータシャッフリングおよび再配布を回避でき、実行効率を大幅に向上させることができます。したがって、l_orderkey を分散キーとして設定してください。

  • lineitem テーブルの最終的なテーブルスキーマは以下のとおりです:

    BEGIN;
    CREATE TABLE hologres_dataset_tpch_100g.lineitem
    (
        l_ORDERKEY      BIGINT      NOT NULL,
        L_PARTKEY       INT         NOT NULL,
        L_SUPPKEY       INT         NOT NULL,
        L_LINENUMBER    INT         NOT NULL,
        L_QUANTITY      DECIMAL(15,2) NOT NULL,
        L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
        L_DISCOUNT      DECIMAL(15,2) NOT NULL,
        L_TAX           DECIMAL(15,2) NOT NULL,
        L_RETURNFLAG    TEXT        NOT NULL,
        L_LINESTATUS    TEXT        NOT NULL,
        L_SHIPDATE      TIMESTAMPTZ NOT NULL,
        L_COMMITDATE    TIMESTAMPTZ NOT NULL,
        L_RECEIPTDATE   TIMESTAMPTZ NOT NULL,
        L_SHIPINSTRUCT  TEXT        NOT NULL,
        L_SHIPMODE      TEXT        NOT NULL,
        L_COMMENT       TEXT        NOT NULL,
        PRIMARY KEY (L_ORDERKEY,L_LINENUMBER)
    )
    WITH (
        distribution_key = 'L_ORDERKEY',--テーブル結合時にローカル JOIN を有効化します。
        clustering_key = 'L_SHIPDATE',--範囲フィルタリングを高速化します。
        event_time_column = 'L_SHIPDATE'--ファイルプルーニングを高速化します。
      );
    COMMIT;

hologres_dataset_tpch_100g.orders

本例では、Q4 クエリで orders テーブルが使用されます。

  • ローカル JOIN 機能を活用し、結合クエリの効率を向上させるために、orders テーブルの o_orderkey フィールドを分散キーとして設定してください。

  • o_orderdate フィールドは、主に日付フィールドに対するフィルタリングクエリで使用されます。ファイルプルーニングを高速化するために、セグメントキーとして設定できます。

  • orders テーブルの最終的なテーブルスキーマは以下のとおりです:

    BEGIN;
    CREATE TABLE hologres_dataset_tpch_100g.orders
    (
        O_ORDERKEY      BIGINT      NOT NULL PRIMARY KEY,
        O_CUSTKEY       INT         NOT NULL,
        O_ORDERSTATUS   TEXT        NOT NULL,
        O_TOTALPRICE    DECIMAL(15,2) NOT NULL,
        O_ORDERDATE     timestamptz NOT NULL,
        O_ORDERPRIORITY TEXT        NOT NULL,
        O_CLERK         TEXT        NOT NULL,
        O_SHIPPRIORITY  INT         NOT NULL,
        O_COMMENT       TEXT        NOT NULL
    )
    WITH (
        distribution_key = 'O_ORDERKEY',--テーブル結合時にローカル JOIN を有効化します。
        event_time_column = 'O_ORDERDATE'--ファイルプルーニングを高速化します。
      );
    COMMIT;

サンプルデータのインポート

HoloWeb のワンクリックパブリックデータセットインポート機能を使用して、TPC-H 100 GB データセットを Hologres インスタンスに迅速にインポートできます。詳細については、「パブリックデータセットのインポート」をご参照ください。

パフォーマンステスト結果の比較

テーブルに適切なプロパティ(インデックス)を設定した後、最適化前後のパフォーマンスをテストできます。

  • テスト環境

    • インスタンスタイプ:32 コア。

    • ネットワークタイプ:VPC。

    • PSQL クライアントを使用してクエリを 2 回実行し、2 回目の実行時間を記録します。

  • テストの結論

    • 単一テーブルに対するフィルタリングクエリでは、フィルター対象のフィールドをクラスタリングキーとして設定することで、クエリを大幅に高速化できます。

    • 複数テーブルの結合クエリでは、結合対象のフィールドを分散キーとして設定することで、結合効率を大幅に向上させることができます。

    クエリ

    Hologres インデックスありの遅延

    Hologres インデックスなしの遅延

    Q1

    48.293 ms

    59.483 ms

    Q4

    822.389 ms

    3027.957 ms

付録

さらに詳しく

技術原理

Hologres のアーキテクチャ、ストレージエンジン、コンピュートエンジンなどのコア原理について学ぶには、「Alibaba Cloud のクラウドネイティブリアルタイムデータウェアハウスのコア技術」をご参照ください。

サービスの有効化

データインポート

データクエリ

サービスモニタリング

ベストプラクティスおよびユースケース

ベストプラクティスおよびユースケースのコレクションについては、「典型的な業界シナリオおよび代表的な顧客ユースケースのベストプラクティス」をご参照ください。