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

Hologres:イベントタイム列 (セグメントキー)

最終更新日:Jan 11, 2025

主キーに基づいて UPDATE 操作を実行する場合、または大規模なデータセットに対して範囲フィルター条件を含むクエリを実行する場合は、テーブルのイベントタイム列を設定できます。システムは、イベントタイム列に基づいてデータファイルをソートし、データファイルを結合します。これにより、重複ファイルが削減され、できるだけ多くのファイルが除外されます。このようにして、クエリの効率が向上します。イベントタイム列を適切に設定することで、データベースの処理効率、クエリ速度、および全体的なパフォーマンスを向上させることができます。このトピックでは、Hologres でテーブルのイベントタイム列を設定する方法について説明します。

概要

Hologres V0.9 では、segment_key プロパティの名前がデフォルトで event_time_column に変更されました。ただし、segment_key プロパティは Hologres V0.9 以前でも使用できます。

イベントタイム列は、次のシナリオに適用できます。

  • 等価条件を含む、範囲フィルター条件を含むクエリ。

  • 主キーに基づく UPDATE 操作。

テーブルを作成するときに、テーブルのイベントタイム列を指定する必要があります。イベントタイム列を設定するには、次の構文を使用します。

-- Hologres V2.1 以降でサポートされている構文
CREATE TABLE <table_name> (...) WITH (event_time_column = '[<columnName>[,...]]');

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

次の表は、上記の構文のパラメーターを示しています。

パラメーター

説明

table_name

イベントタイム列を設定するテーブルの名前。

columnName

イベントタイム列として設定する列の名前。

使用上の注意

  • タイムスタンプ列など、データが単調に増加または減少する列をイベントタイム列として設定することをお勧めします。 event_time_column プロパティは、ログ列やトラフィック列など、時間と強い相関関係のある列に適用できます。このプロパティを適切に設定することで、クエリのパフォーマンスを向上させることができます。複数のファイルがマージされた後、イベントタイム列のデータが順序付けられていない場合、各ファイルのデータには識別機能がなく、順序付けられていません。この場合、データフィルタリングの効果は低くなります。

  • テーブルにデータが単調に増加または減少する列が含まれていない場合は、update_time 列を追加し、イベントタイム列として使用できます。 UPSERT 操作を実行するたびに、現在の時刻が update_time 列に書き込まれます。

  • イベントタイム列に基づくデータクエリは、左端一致の原則に従います。したがって、テーブルに複数のイベントタイム列を指定しないことをお勧めします。指定した場合、イベントタイム列に基づくデータクエリが一部のシナリオで高速化されない可能性があります。ほとんどの場合、テーブルに 1 つまたは 2 つのイベントタイム列を指定することをお勧めします。

制限事項

  • テーブルのイベントタイム列は、NOT NULL 制約を満たす必要があります。 Hologres V1.3.20 から V1.3.27 では、NULL 値を含む列をイベントタイム列として指定できます。 Hologres V1.3.28 以降では、NULL 値を含む列をイベントタイム列として指定することはできません。これは、イベントタイム列に NULL 値が含まれていると、データの精度に悪影響を与える可能性があるためです。ビジネス要件に基づいて NULL 値を含む列をイベントタイム列として指定する必要がある場合は、CREATE TABLE ステートメントの前に次の SET コマンドを追加できます。

    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 プロパティは変更できません。プロパティを変更する場合は、別のテーブルを作成してください。

  • 行指向テーブルの event_time_column プロパティは設定できません。

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

  • DECIMAL、NUMERIC、FLOAT、DOUBLE、ARRAY、JSON、JSONB、BIT、MONEY データ型、およびその他の複合データ型の列はサポートされていません。

仕組

次の図は、シャード内のデータの書き込み方法を示しています。分段键技术原理

  1. シャード内のデータは、最初にメモリテーブルに書き込まれます。最大の書き込み効率を実現するために、追加専用モードを使用してデータを書き込みます。メモリテーブルのサイズは制限されています。メモリテーブルがいっぱいになると、Hologres はメモリテーブル内のデータをファイルに非同期的にフラッシュします。

  2. 書き込み効率を最大化するために、データは追加専用モードでファイルに書き込まれ、ファイルの数は時間の経過とともに増加します。この場合、Hologres は定期的にファイルをマージします。 event_time_column プロパティが設定されている場合、Hologres はプロパティで指定された範囲に基づいてファイルをソートし、データの範囲が隣接するファイルを選択して、これらのファイルをマージします。これにより、ファイル間の重複が減り、クエリ中に不要なファイルが除外されます。この場合、クエリの効率が向上します。

  3. ファイルは、イベントタイム列に基づいてソートされます。イベントタイム列に基づくデータクエリは、左端一致の原則に従います。列 abc をイベントタイム列として指定した場合、列 a、b、c のクエリ、または列 a と b のクエリは、イベントタイム列にヒットします。列 a と c をクエリする場合、列 a のクエリのみがイベントタイム列にヒットします。列 b と c をクエリする場合、クエリはイベントタイム列にヒットしません。

上記の内容は、次のシナリオでイベントタイム列を使用してデータクエリを高速化できることを示しています。

  • 等価条件を含む、範囲フィルター条件を含むクエリ。

    クエリ対象の列がイベントタイム列として指定されている場合、Hologres はデータのスキャン時に、範囲フィルター条件に基づいてファイル内の列の統計 (最小/最大) を比較して、必要なファイルをフィルタリングします。これにより、クエリプロセスが高速化されます。

  • 主キーに基づく UPDATE 操作。

    Hologres では、UPDATE 操作は、DELETE 操作と INSERT 操作の組み合わせに相当します。テーブルに主キーを設定した後、UPDATE ステートメントまたは INSERT ON CONFLICT ステートメントを実行すると、Hologres は主キーに基づいて、ターゲットテーブルに指定したイベントタイム列の値を見つけます。次に、Hologres はイベントタイム列に基づいて、既存のデータが存在するファイルを見つけます。最後に、Hologres は既存のデータを見つけて、データを DELETE としてマークします。 UPDATE ステートメントと INSERT ON CONFLICT ステートメントの詳細については、「UPDATE」または「INSERT ON CONFLICT(UPSERT)」をご参照ください。適切なイベントタイム列は、既存のデータが存在するファイルをすばやく見つけるのに役立ちます。これにより、書き込みパフォーマンスが向上します。次のシナリオでは、データクエリ中に多数のファイルをスキャンする必要があります。(1) 列指向テーブルにイベントタイム列が指定されていない。 (2) 設定したイベントタイム列が適切でない。 (3) 設定したイベントタイム列が時間と強い相関関係がなく、順序付けられていないデータが含まれている。この場合、多数の 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';
    • すべての Hologres バージョンでサポートされている構文:

      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 が含まれている場合、クエリはイベントタイム列にヒットします。分段键执行计划

  • テーブルを作成するときに、複数の列をイベントタイム列として設定します。

    • 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';
    • すべての Hologres バージョンでサポートされている構文:

      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';

関連情報