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

Hologres:Hologresインデックスの概要

最終更新日:Jan 11, 2025

このトピックでは、分散キー、イベントタイム列(セグメントキー)、クラスタリングキーなど、Hologresでサポートされているインデックスについて説明します。Hologres開発でインデックスをすばやく使用してクエリのパフォーマンスを向上させるのに役立ちます。

Hologresのしくみ

Hologresは、並列コンピューティングとベクトルコンピューティング技術を使用してクエリに数秒で応答する分散データウェアハウスです。分散キーイベントタイム列はデータ分散を決定し、クエリのパフォーマンスに重大な影響を与えます。データは分散キーに基づいてノードに分散され、ファイルはイベントタイム列に基づいてノード内でソートされます。オンライン分析処理(OLAP)シナリオでは、Hologresでは列指向ストレージがデフォルトで使用されます。クラスタリングキーの設定も重要です。これは、ファイル内でのデータのソート方法を決定するためです。適切なインデックス設定により、クエリのパフォーマンスを大幅に向上させることができます。テーブルを作成するときは、分散キー、イベントタイム列、およびクラスタリングキーを設定してデータ分散を決定することをお勧めします。既存のテーブルに対してこれらのインデックスを設定する場合、調整コストは高くなります。既存のテーブルの場合、ビジネス要件に基づいて、ビットマップインデックスや辞書エンコードプロパティなど、データ分散に直接影響しない他のインデックスを設定できます。

Hologresのメタデータは、データベース層、スキーマ層、テーブル層の3層モデルを使用します。論理的に関連するテーブルは同じスキーマに格納して、データベース間のクエリを防ぐことをお勧めします。メタデータはデータベースによって分離されますが、リソースはデータベースによって分離されません。

SQL最適化の基本原則:I/Oリソース消費の削減と並行性の最適化

テーブルを作成するときにデータ分散に適切なインデックスを設定すると、SQLステートメントが実行された後にクエリするデータがすぐに見つかります。これにより、I/Oおよびコンピューティングリソースの消費が削減され、クエリが高速化されます。バランスの取れたデータ分散は、同時リソースの利用率を高め、単一ノードのボトルネックを防ぐのにも役立ちます。次の図は、SQLステートメントの実行からデータの取得までの実行プロセスを示しています。これにより、I/Oリソース消費がどのように削減されるかを理解できます。image

  • パーティションプルーニング:パーティションテーブルでSQLクエリを実行すると、システムはパーティションプルーニング機能を使用して、必要なデータが配置されているパーティションを見つけます。クエリ条件に基づいて一致するパーティションがない場合、システムはすべてのパーティションをトラバースする必要があり、過剰なI/Oリソースが消費されます。ほとんどの場合、日ごとのパーティション分割がより適切です。パーティション化されていないテーブルの場合、パーティションプルーニングは関係ありません。

  • シャードプルーニング:分散キーを使用して、目的のデータが配置されているシャードをすばやく見つけることができます。これにより、単一のSQLステートメントに必要なリソースが削減され、複数のSQLステートメントが同時に実行される場合の高いスループットがサポートされます。特定のシャードが見つからない場合、システムは分散フレームワークに基づいてすべてのシャードを計算用にスケジュールします。この場合、単一のSQLステートメントが複数のシャードで実行されるため、大量のリソースが消費され、システム全体の並行性が低下します。特定の演算子が集中方式で実行されると、追加のシャッフルオーバーヘッドが発生します。ほとんどの場合、注文ID、ユーザーID、イベントIDフィールドなど、値が均等に分散されているフィールドを分散キーフィールドとして設定できます。結合するテーブルに同じ分散キーを設定して、相関データを同じシャードに分散できるようにすることをお勧めします。これにより、ローカル結合操作で高い効率を実現できます。

  • セグメントキープルーニング:イベントタイム列を使用して、必要なデータが配置されているファイルをノード上の複数のファイルからすばやく見つけることができます。これにより、他のファイルにアクセスする必要がなくなります。フィルタリングに失敗した場合、システムはすべてのファイルをトラバースする必要があります。

  • クラスタリングキープルーニング:クラスタリングキーを使用して、ファイル内の目的のデータ範囲をすばやく見つけることができます。これにより、範囲クエリとフィールドソートの効率が向上します。

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つのテーブルに同じインデックスを設定して、ローカル結合を許可します。これにより、2つのテーブル間のデータシャッフリングが削減されます。

    --TPC-H Q4
    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;

テーブル作成の推奨事項

このセクションでは、TPC-H Q1およびQ4で使用されるlineitemテーブルとordersテーブルを作成するための推奨事項を示します。

hologres_dataset_tpch_100g.lineitem

lineitemテーブルのインデックス設定とクエリ条件は、TPC-H Q1とTPC-H Q4で異なります。

  • TPC-H Q1:l_shipdate列は、ファイル内のデータの時間シーケンスを指定し、範囲フィルタリングに使用されます。範囲フィルタリングを高速化するために、l_shipdate列をクラスタリングキー列として設定できます。イベントタイム列は、ファイルをソートするために使用されます。ファイルのフィルタリングを容易にするために、日付が単調に増加または減少する日付列をイベントタイム列として設定することをお勧めします。 TPC-H Q1では、l_shipdate列をイベントタイム列として設定できます。

  • TPC-H Q4:結合クエリは、lineitemテーブルのl_orderkey列とordersテーブルのo_orderkey列に基づいて実行されます。データは分散キーに基づいて分散されます。システムは、同じ分散キー値を持つデータレコードを同じシャードに分散します。 2つのテーブルが同じテーブルグループに格納され、分散キーに基づいて結合されている場合、システムは同じ分散キー値を持つデータレコードを同じシャードに自動的に分散します。データ書き込み中に、現在のノードでローカル結合が実行され、結合キーに基づくデータシャッフリングは必要ありません。これにより、実行時のデータの分散と再分散が防止され、実行効率が大幅に向上します。したがって、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',-- 分散キーを指定してローカル結合を許可します。
        clustering_key = 'L_SHIPDATE',-- クラスタリングキーを指定して範囲フィルタリングを高速化します。
        event_time_column = 'L_SHIPDATE'-- イベントタイム列を指定してファイルプルーニングを高速化します。
      );
    COMMIT;

hologres_dataset_tpch_100g.orders

この例では、TPC-H Q4 で orders テーブルが使用されます。

  • ローカル結合を許可するために、orders テーブルの o_orderkey 列を分散キーとして構成します。これにより、結合クエリの効率が向上します。

  • ファイルのプルーニングを高速化するために、orders テーブルの o_orderdate 列をイベント時間列として構成します。 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',-- 分散キーを指定して、ローカル結合を許可します。
        event_time_column = 'O_ORDERDATE'-- イベント時間列を指定して、ファイルのプルーニングを高速化します。
      );
    COMMIT;

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

HoloWeb を使用すると、数回クリックするだけで TPC-H パブリック データセットから 100 GB のデータを Hologres インスタンスにインポートできます。詳細については、「数回クリックするだけでパブリック データセットをインポートする」をご参照ください。

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

このセクションでは、テーブルにインデックスが構成される前後のパフォーマンス テストの結果について説明します。

  • テスト環境

    • インスタンス仕様: 32 CPU コア

    • ネットワークタイプ: virtual private cloud (VPC)

    • PostgreSQL クライアントで各クエリを 2 回実行し、2 回目のクエリのレイテンシを使用します。

  • テストの結論

    • フィルタリングを含む単一テーブルに対するクエリの場合、データがフィルタリングされる基準となる列をクラスタリングキー列として構成することで、クエリを大幅に高速化できます。

    • 複数テーブル結合クエリの場合、結合列を分散キー列として構成することで、結合操作を大幅に高速化できます。

    クエリ

    Hologres でインデックスが構成されている場合のレイテンシ

    Hologres でインデックスが構成されていない場合のレイテンシ

    Q1

    48.293 ms

    59.483 ms

    Q4

    822.389 ms

    3027.957 ms

参照資料

さらに読む

サービスのアクティベーション

データのインポート

データクエリ

O&M とモニタリング