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

Hologres:イベント時間列 (セグメントキー)

最終更新日:Aug 21, 2026

大規模なデータセットに対して、プライマリキー に基づく UPDATE 操作や 範囲フィルター 条件を含むクエリを頻繁に実行する場合、イベント時間列 (セグメントキー) の設定を検討してください。システムは、ファイルをマージする前に イベント時間列 の範囲に基づいてデータファイルを並べ替えます。このプロセスにより、ファイル間の重複が減少し、クエリエンジンが可能な限り多くのファイルをプルーニングできるようになり、クエリ効率が向上します。適切に設定された イベント時間列 は、クエリ速度と全体的なパフォーマンスを向上させます。このトピックでは、Hologres のテーブルに event_time_column プロパティを設定する方法を説明します。

イベント時間列

event_time_column プロパティは、以前は セグメントキー という名前でした。Hologres V0.9 以降では、デフォルトのプロパティ名は event_time_column です。セグメントキー プロパティは、下位互換性のために保持されています。

イベント時間列 は、主に次のシナリオで使用されます。

  • 範囲フィルター または 等値条件 を含むクエリ。

  • プライマリキー に基づく UPDATE 操作。

event_time_column プロパティは、テーブルの作成時に指定する必要があります。次の構文を使用します。

-- Hologres V2.1 以降でサポートされている構文
CREATE TABLE <table_name> (...) WITH (event_time_column = '[<columnName>[,...]]');
-- すべてのバージョンでサポートされている構文
BEGIN;
CREATE TABLE <table_name> (...);
call set_table_property('<table_name>', 'event_time_column', '[<columnName>[,...]]');
COMMIT;

パラメーター:

パラメーター

説明

table_name

テーブルの名前。

columnName

イベント時間列 として使用する列。

推奨事項

  • イベント時間列 は、タイムスタンプ列など、単調に増加または減少する値を持つ列に最適です。ログやトラフィックデータなどの時間関連データに理想的であり、適切な設定によってパフォーマンスを大幅に向上させることができます。イベント時間列 が完全に順不同である場合、マージされたファイルは明確な値の範囲を持たず、ファイルプルーニングの利点が失われます。

  • テーブルに明確な単調増加または単調減少の列がない場合は、update_time などの列を追加し、各 アップサート 操作で現在の時刻を書き込むことを検討してください。

  • イベント時間列最左一致の原則 に従います。複数の列を設定すると、高速化の対象となるクエリパターンが制限される可能性があります。したがって、ほとんどの場合、2列以下を指定することを推奨します。

制限事項

  • イベント時間列 は、NOT NULL として定義されている列または列の組み合わせである必要があります。event_time_column プロパティを省略することはできますが、NULL 値を許可する列に設定することはできません。Hologres V1.3.20 から V1.3.27 までは、event_time_column プロパティに NULL 値を許容する列の指定がサポートされていました。Hologres V1.3.28 以降、NULL 値を許容する イベント時間列 はデータ整合性を損なう可能性があるため、この機能はサポートされなくなりました。ビジネス要件上、NULL 値を許容する列を イベント時間列 として設定する必要がある場合は、SQL ステートメントの前に次のステートメントを追加できます。

    set hg_experimental_enable_nullable_segment_key = true;

    次の SQL ステートメントを使用して、現在のデータベースに NULL 値を許容する イベント時間列 (または セグメントキー) が含まれているか確認できます。

    WITH t_base AS (
        SELECT
            *
        FROM
            hologres.hg_table_info
        WHERE
            collect_time::date = CURRENT_DATE
    ),
    t1 AS (
        SELECT
            db_name,
            schema_name,
            table_name,
            jsonb_array_elements(table_meta::jsonb -> 'columns') cols
        FROM
            t_base
    ),
    t2 AS (
        SELECT
            db_name,
            schema_name,
            table_name,
            cols ->> 'name' col_name
        FROM
            t1
        WHERE
            cols -> 'nullable' = 'true'::jsonb
    ),
    t3 AS (
        SELECT
            db_name,
            schema_name,
            table_name,
            regexp_replace(regexp_split_to_table(table_meta::jsonb ->> 'segment_key', ','), ':asc|:desc$', '') segment_key_col
        FROM
            t_base
        WHERE
            table_meta::jsonb -> 'segment_key' IS NOT NULL
    )
    SELECT
        CURRENT_DATE,
        t3.db_name,
        t3.schema_name,
        t3.table_name,
        jsonb_build_object('nullable_segment_key_column', string_agg(t3.segment_key_col, ',')) as nullable_segment_key_column
    FROM
        t2,
        t3
    WHERE
        t3.db_name = t2.db_name
        AND t3.schema_name = t2.schema_name
        AND t3.table_name = t2.table_name
        AND t2.col_name = t3.segment_key_col
    GROUP BY
        t3.db_name,
        t3.schema_name,
        t3.table_name;
    
  • テーブルの作成後に event_time_column プロパティを変更することはできません。変更するには、テーブルを再作成する必要があります。

  • 行指向テーブルイベント時間列 を設定することはできません。

  • 列指向テーブル の場合、イベント時間列 を明示的に設定しないと、Hologres はデフォルトで、TIMESTAMP または TIMESTAMPTZ データ型の最初の NOT NULL 列を イベント時間列 として使用します。そのような列が存在しない場合は、DATE データ型の最初の NOT NULL 列が使用されます。Hologres V0.9 より前のバージョンでは、デフォルトの イベント時間列 は設定されません。

  • DECIMALNUMERICFLOATDOUBLEARRAYJSONJSONBBITMONEY、またはその他の複雑なデータ型を イベント時間列 として使用することはできません。

仕組み

次の図は、単一の シャード 内でのデータ書き込みプロセスを示しています。分段键技术原理

  1. シャード 内では、書き込みパフォーマンスを最大化するために、データはまず追記専用モードで インメモリテーブル に書き込まれます。インメモリテーブル のサイズは固定です。インメモリテーブル がいっぱいになると、システムはそのデータを非同期でファイルにフラッシュします。

  2. 書き込みパフォーマンスを最適化するために、データは追記専用モードで書き込まれ、時間の経過とともにファイル数が増加します。システムはバックグラウンドでこれらのファイルを定期的にマージします。イベント時間列 (または セグメントキー) を設定すると、システムは イベント時間列 の範囲に基づいてファイルを並べ替え、隣接する範囲のファイルをマージします。このプロセスにより、ファイル間の重複が減少し、クエリオプティマイザーがより多くのファイルをプルーニングできるようになり、クエリ効率が向上します。

  3. ファイルは イベント時間列 に基づいてソートされます。したがって、イベント時間列最左一致の原則 に従います。たとえば、列 abcイベント時間列 として設定した場合、フィルター条件が a,b,c または a,b の場合、クエリはこの設定の恩恵を受けられます。フィルター条件が a,c の場合、列 a のみが恩恵を受けます。フィルター条件が b,c の場合、クエリは イベント時間列 の恩恵を受けられません。

前述のように、イベント時間列 は次のシナリオを高速化できます。

  • 範囲フィルター または 等値条件 を含むクエリ。

    クエリ対象の列が イベント時間列 として設定されている場合、Hologres はクエリ内の範囲条件を列のファイルレベルの統計情報 (min/max) と比較します。これにより、Hologres は無関係なファイルを迅速にプルーニングし、クエリを高速化できます。

  • プライマリキー に基づく UPDATE 操作。

    Hologres の UPDATE コマンドは、DELETE コマンドと INSERT コマンドの組み合わせとして実装されています。プライマリキーベースの UPDATE または INSERT ON CONFLICT (アップサート) を伴うシナリオでは、まずプライマリキーを使用してターゲットテーブル内の古いデータのセグメントキーを見つけます。次に、このセグメントキーを使用して古いデータを含むファイルを特定し、最終的にデータを DELETE としてマークします。セグメントキーが適切に設定されていれば、古いデータを含むファイルを迅速に特定でき、書き込みパフォーマンスが向上します。逆に、列指向テーブルにセグメントキーが設定されていない場合、セグメントキーが不適切なフィールドで設定されている場合、またはデータ書き込み時にセグメントキーのフィールドが時間と強い相関関係を持たない場合 (たとえば、データがほとんど順不同である場合) は、古いデータを見つけるために多数のファイルをスキャンする必要があります。このプロセスは、多数の I/O 操作を引き起こすだけでなく、大量の CPU リソースを消費し、書き込みパフォーマンスとインスタンス全体の負荷に悪影響を及ぼします。

  • テーブル作成時に単一の イベント時間列 を作成する。

    • Hologres V2.1 以降でサポートされている構文:

      CREATE TABLE tbl_segment_test (
          a int NOT NULL,
          b timestamptz NOT NULL
      )
      WITH (
          event_time_column = 'b'
      );
      INSERT INTO tbl_segment_test values
      (1,'2022-09-05 10:23:54+08'),
      (2,'2022-09-05 10:24:54+08'),
      (3,'2022-09-05 10:25:54+08'),
      (4,'2022-09-05 10:26:54+08');
      EXPLAIN SELECT * FROM tbl_segment_test WHERE b > '2022-09-05 10:24:54+08';
    • すべてのバージョンでサポートされている構文:

      BEGIN;
      CREATE TABLE tbl_segment_test (
          a int NOT NULL,
          b timestamptz NOT NULL
          );
      CALL set_table_property('tbl_segment_test', 'event_time_column', 'b');
      COMMIT;
      INSERT INTO tbl_segment_test VALUES 
      (1,'2022-09-05 10:23:54+08'),
      (2,'2022-09-05 10:24:54+08'),
      (3,'2022-09-05 10:25:54+08'),
      (4,'2022-09-05 10:26:54+08');
      EXPLAIN SELECT * FROM tbl_segment_test WHERE b > '2022-09-05 10:24:54+08';

    EXPLAIN ステートメントを実行すると、実行計画 を確認できます。計画に Segment Filter が表示される場合、クエリは イベント時間列 を使用しています。次の計画には Segment Filter が含まれており、イベント時間列 が有効であることを示しています。

    QUERY PLAN
    Gather  (cost=0.00..1.10 rows=1 width=12)
      -> Exchange (Gather Exchange)  (cost=0.00..1.10 rows=1 width=12)
        -> Decode  (cost=0.00..1.10 rows=1 width=12)
          -> Index Scan using holo_index:[1] on tbl_segment_test  (cost=0.00..1.00 rows=1 width=12)
                Segment Filter: (b > '2022-09-05 10:24:54+08'::timestamp with time zone)
    Optimizer: HQO version 1.3.0
  • テーブル作成時に複数の イベント時間列 を作成する。

    • Hologres V2.1 以降でサポートされている構文:

      CREATE TABLE tbl_segment_test_2 (
          a int NOT NULL,
          b timestamptz NOT NULL
      )
      WITH (
          event_time_column = 'a,b'
      );
      INSERT INTO tbl_segment_test_2 VALUES 
      (1,'2022-09-05 10:23:54+08'),
      (2,'2022-09-05 10:24:54+08'),
      (3,'2022-09-05 10:25:54+08'),
      (4,'2022-09-05 10:26:54+08')
      ;
      -- クエリはイベント時間列を使用しません。
      SELECT * FROM tbl_segment_test_2 WHERE b > '2022-09-05 10:24:54+08';
      -- クエリはイベント時間列を使用します。
      SELECT * FROM tbl_segment_test_2 WHERE a = 3 and b > '2022-09-05 10:24:54+08';
      SELECT * FROM tbl_segment_test_2 WHERE a > 3 and b < '2022-09-05 10:26:54+08';
      SELECT * FROM tbl_segment_test_2 WHERE a > 3 and b > '2022-09-05 10:24:54+08';
    • すべてのバージョンでサポートされている構文:

      BEGIN;
      CREATE TABLE tbl_segment_test_2 (
          a int NOT NULL,
          b timestamptz NOT NULL
          );
      CALL set_table_property('tbl_segment_test_2', 'event_time_column', 'a,b');
      COMMIT;
      INSERT INTO tbl_segment_test_2 VALUES 
      (1,'2022-09-05 10:23:54+08'),
      (2,'2022-09-05 10:24:54+08'),
      (3,'2022-09-05 10:25:54+08'),
      (4,'2022-09-05 10:26:54+08')
      ;
      -- クエリはイベント時間列を使用しません。
      SELECT * FROM tbl_segment_test_2 WHERE b > '2022-09-05 10:24:54+08';
      -- クエリはイベント時間列を使用します。
      SELECT * FROM tbl_segment_test_2 WHERE a = 3 and b > '2022-09-05 10:24:54+08';
      SELECT * FROM tbl_segment_test_2 WHERE a > 3 and b < '2022-09-05 10:26:54+08';
      SELECT * FROM tbl_segment_test_2 WHERE a > 3 and b > '2022-09-05 10:24:54+08';

関連トピック