Hologres は、行指向、列指向、行列ハイブリッドの 3 種類のテーブルストレージフォーマットをサポートしています。各フォーマットは異なるクエリシナリオに適しています。ユースケースに基づいてテーブルのストレージフォーマットを設定できます。適切なストレージフォーマットは、データ処理とクエリ速度を大幅に向上させ、ストレージ容量を削減できます。
ストレージフォーマットの構文設定
Hologres は、行指向、列指向、行列ハイブリッドのストレージフォーマットをサポートしています。テーブルを作成する際に、orientation プロパティを設定することで、そのストレージフォーマットを指定できます。構文は次のとおりです。
-- Hologres V2.1 以降でサポート
CREATE TABLE <table_name> (...) WITH (orientation = '[column | row | row,column]');
-- すべてのバージョンでサポート
BEGIN;
CREATE TABLE <table_name> (...);
CALL set_table_property('<table_name>', 'orientation', '[column | row | row,column]');
COMMIT;table_name:テーブルの名前。
orientation:テーブルが列指向、行指向、または行列ハイブリッドのストレージモデルを使用するかどうかを指定します。Hologres は V1.1 以降、行列ハイブリッドモデルをサポートしています。
デフォルトでは、テーブルは列指向ストレージで作成されます。テーブルを作成する際に、行指向または行列ハイブリッドストレージを明示的に指定する必要があります。テーブルのストレージフォーマットを変更するには、テーブルを再作成する必要があります。直接的な変換はサポートされていません。
利用推奨
推奨されるテーブルストレージフォーマットは次のとおりです。
ストレージフォーマット | シナリオ | 列数の上限 | 注意事項 |
列指向 | オンライン分析処理 (OLAP) シナリオに適しています。このフォーマットは、複雑なクエリ、データ結合、スキャン、フィルタリング、集約に最適です。 | 最大 300 列を推奨します。 | 列指向ストレージは、デフォルトでより多くのインデックスを作成します。これには文字列型のビットマップインデックスも含まれます。これらのインデックスは、クエリのフィルタリングと集約を大幅に高速化できます。 |
行指向 | プライマリキーに基づくポイントクエリシナリオに最適です。クエリ文の例を以下に示します。 | 最大 3,000 列を推奨します。 | 行指向ストレージは、デフォルトでプライマリキーにのみインデックスを作成します。プライマリキーに基づく高速なクエリのみをサポートするため、ユースケースが限定されます。 |
行列ハイブリッド | 行指向と列指向ストレージの両方のすべてのシナリオをサポートし、さらにプライマリキー以外の列に対するポイントクエリもサポートします。 | 最大 300 列を推奨します。 | 行列ハイブリッドフォーマットはより広範なシナリオに適用できますが、ストレージと内部データ同期のオーバーヘッドが大きくなります。 |
技術的原則
列指向ストレージ
テーブルが列指向の場合、そのデータは列ごとに保存されます。列指向ストレージは、デフォルトで ORC フォーマットを使用します。ランレングスエンコーディング (RLE) や辞書エンコーディングなど、さまざまなエンコーディングアルゴリズムを使用してデータをエンコードします。その後、Snappy、Zlib、Zstd、Lz4 などの主要な圧縮アルゴリズムを使用して、エンコードされたデータをさらに圧縮します。このアプローチは、ビットマップインデックスや遅延マテリアライゼーションなどのメカニズムと組み合わせることで、ストレージとクエリの効率を向上させます。
システムは、ストレージレイヤーに各テーブルのプライマリキーインデックスファイルを保存します。詳細については、「プライマリキー」をご参照ください。列指向テーブルにプライマリキー (PK) が設定されている場合、システムは自動的に行識別子 (RID) を生成して行全体を迅速に特定します。クエリ対象の列に分散キーやクラスタリングキーなどの適切なインデックスも設定すると、これらのインデックスを使用してデータのシャードとファイルを迅速に特定できます。これにより、クエリのパフォーマンスが向上します。したがって、列指向ストレージはより汎用性が高く、通常は OLAP クエリシナリオで使用されます。以下の例は、列指向テーブルの作成方法を示しています。
Hologres V2.1 以降の構文:
CREATE TABLE public.tbl_col ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT NOT NULL, in_time TIMESTAMPTZ NOT NULL, PRIMARY KEY (id) ) WITH ( orientation = 'column', clustering_key = 'class', bitmap_columns = 'name', event_time_column = 'in_time' ); SELECT * FROM public.tbl_col WHERE id ='3333'; SELECT id, class,name FROM public.tbl_col WHERE id < '3333' ORDER BY id;すべてのバージョンの構文:
BEGIN; CREATE TABLE public.tbl_col ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT NOT NULL, in_time TIMESTAMPTZ NOT NULL, PRIMARY KEY (id) ); CALL set_table_property('public.tbl_col', 'orientation', 'column'); CALL set_table_property('public.tbl_col', 'clustering_key', 'class'); CALL set_table_property('public.tbl_col', 'bitmap_columns', 'name'); CALL set_table_property('public.tbl_col', 'event_time_column', 'in_time'); COMMIT; SELECT * FROM public.tbl_col WHERE id ='3333'; SELECT id, class,name FROM public.tbl_col WHERE id < '3333' ORDER BY id;
次の図は、そのプロセスを示しています。
行指向ストレージ
Hologres テーブルが行指向に設定されている場合、そのデータは行ごとに保存されます。行指向ストレージは、デフォルトで SST フォーマットを使用します。データはキーでソートされ、ブロックに分割された後、圧縮されます。ブロックインデックスやブルームフィルターなどのインデックスと、バックグラウンドコンパクションメカニズムを使用してファイルを整理し、ポイントクエリの効率を最適化します。
(推奨) プライマリキーの設定
システムは、ストレージレイヤーに各テーブルのプライマリキーインデックスファイルを保存します。詳細については、「プライマリキー」をご参照ください。行指向テーブルにプライマリキー (PK) が設定されている場合、システムは自動的に行識別子 (RID) を生成します。RID は行全体を特定するために使用されます。システムはまた、PK を分散キーおよびクラスタリングキーとして設定します。これにより、システムはデータのシャードとファイルを迅速に特定できます。プライマリキーに基づくクエリを含むシナリオでは、単一のプライマリキーをスキャンすることで行のすべての列を迅速に取得でき、クエリ効率が向上します。以下の SQL 例は、行指向テーブルの作成方法を示しています。
Hologres V2.1 以降の構文:
CREATE TABLE public.tbl_row ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT, PRIMARY KEY (id) ) WITH ( orientation = 'row', clustering_key = 'id', distribution_key = 'id' ); -- PK に基づくポイントクエリの例 SELECT * FROM public.tbl_row WHERE id ='1111'; -- 複数のキーのクエリ SELECT * FROM public.tbl_row WHERE id IN ('1111','2222','3333');すべてのバージョンの構文:
BEGIN; CREATE TABLE public.tbl_row ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT , PRIMARY KEY (id) ); CALL set_table_property('public.tbl_row', 'orientation', 'row'); CALL set_table_property('public.tbl_row', 'clustering_key', 'id'); CALL set_table_property('public.tbl_row', 'distribution_key', 'id'); COMMIT; -- PK に基づくポイントクエリの例 SELECT * FROM public.tbl_row WHERE id ='1111'; -- 複数のキーのクエリ SELECT * FROM public.tbl_row WHERE id IN ('1111','2222','3333');
次の図は、そのプロセスを示しています。

(非推奨) PK とクラスタリングキーを異なる列に設定
ただし、行指向テーブルを作成し、PK とクラスタリングキーを異なる列に設定すると、システムはクエリ中に 2 回のスキャンを実行します。最初に PK を使用してクラスタリングキーと RID を特定し、次にクラスタリングキーと RID を使用して完全な行データを特定します。これにより、パフォーマンスのトレードオフが発生します。以下の SQL 例は、PK とクラスタリングキーが異なる列の行指向テーブルの作成方法を示しています。
Hologres V2.1 以降で、PK とクラスタリングキーが異なる列の行指向テーブルを作成する構文:
CREATE TABLE public.tbl_row ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT, PRIMARY KEY (id) ) WITH ( orientation = 'row', clustering_key = 'name', distribution_key = 'id' );すべてのバージョンで、PK とクラスタリングキーが異なる列の行指向テーブルを作成する構文:
BEGIN; CREATE TABLE public.tbl_row ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT , PRIMARY KEY (id) ); CALL set_table_property('public.tbl_row', 'orientation', 'row'); CALL set_table_property('public.tbl_row', 'clustering_key', 'name'); CALL set_table_property('public.tbl_row', 'distribution_key', 'id'); COMMIT;
次の図は、そのプロセスを示しています。

まとめると、行指向テーブルは PK に基づくポイントクエリシナリオに最適であり、ポイントクエリで高い 1 秒あたりのクエリ数 (QPS) を達成できます。行指向テーブルを作成する際は、PK のみを設定してください。システムは自動的に PK を分散キーおよびクラスタリングキーとして使用し、クエリパフォーマンスを向上させます。PK とクラスタリングキーを異なる列に設定すると、パフォーマンスのトレードオフが発生するため、行わないでください。
行列ハイブリッドストレージ
実際のアプリケーションでは、単一のテーブルがプライマリキーのポイントクエリと OLAP クエリの両方に使用されることがよくあります。このため、Hologres は V1.1 で行列ハイブリッドストレージフォーマットを導入しました。このフォーマットは、行指向と列指向の両方のストレージの機能を兼ね備えています。PK に基づくパフォーマンス専有型ポイントクエリと OLAP 分析の両方をサポートします。データはストレージレイヤーに 2 つのコピーで保存されます。1 つは行指向フォーマット、もう 1 つは列指向フォーマットです。これにより、ストレージオーバーヘッドが大きくなります。
データが書き込まれると、行指向と列指向の両方のストアに同時に書き込まれます。両方の書き込みが完了した後にのみ、操作は成功メッセージを返します。これにより、原子性が保証されます。
データがクエリされると、オプティマイザーは SQL 文を解析して実行計画を生成します。その後、実行エンジンは、最も効率的なクエリのために行指向ストアと列指向ストアのどちらを使用するかを決定します。行列ハイブリッドテーブルにはプライマリキーが必要です。
select * from tbl where pk=xxxのようなプライマリキーに基づくポイントクエリシナリオや、Fixed Plan を使用して SQL 実行を高速化するシナリオでは、オプティマイザーはデフォルトで行指向ストアのポイントクエリパスを使用します。詳細については、「Fixed Plan を使用した SQL 実行の高速化」をご参照ください。select * from tbl where col1=xx and col2=yyyのようなプライマリキー以外の列に対するポイントクエリシナリオでは、行列ハイブリッドフォーマットが特に有益です。これは、テーブルに多くの列があり、クエリ結果でそれらの多くを表示する必要がある場合に当てはまります。このシナリオでは、オプティマイザーはまず列指向ストアからデータを読み取る実行計画を生成します。読み取りが完了した後、列指向ストアからのキーと値のペアに基づいて行指向ストアをクエリします。このプロセスにより、フルテーブルスキャンが回避され、プライマリキー以外のクエリのパフォーマンスが向上します。このシナリオでは、行列ハイブリッドフォーマットの利点を最大限に活用して、データ取得速度を向上させます。その他すべての標準的なクエリでは、デフォルトで列指向ストアが使用されます。
したがって、行列ハイブリッドテーブルは、特にプライマリキーを使用しないポイントクエリなど、一般的なシナリオでより優れたクエリパフォーマンスを提供します。以下に例を示します。
Hologres V2.1 以降の構文:
CREATE TABLE public.tbl_row_col ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT NOT NULL, PRIMARY KEY (id) ) WITH ( orientation = 'row,column', distribution_key = 'id', clustering_key = 'class', bitmap_columns = 'name' ); SELECT * FROM public.tbl_row_col WHERE id ='2222'; -- プライマリキーに基づくポイントクエリ SELECT * FROM public.tbl_row_col WHERE class='Class 2';-- プライマリキー以外の列に対するポイントクエリ SELECT * FROM public.tbl_row_col WHERE id ='2222' AND class='Class 2'; -- 標準的な OLAP クエリすべてのバージョンの構文:
BEGIN; CREATE TABLE public.tbl_row_col ( id TEXT NOT NULL, name TEXT NOT NULL, class TEXT , PRIMARY KEY (id) ); CALL set_table_property('public.tbl_row_col', 'orientation','row,column'); CALL set_table_property('public.tbl_row_col', 'distribution_key','id'); CALL set_table_property('public.tbl_row_col', 'clustering_key','name'); CALL set_table_property('public.tbl_row_col', 'bitmap_columns','class'); COMMIT; SELECT * FROM public.tbl_row_col WHERE id ='2222'; -- プライマリキーに基づくポイントクエリ SELECT * FROM public.tbl_row_col WHERE class='Class 2';-- プライマリキー以外の列に対するポイントクエリ SELECT * FROM public.tbl_row_col WHERE id ='2222' AND class='Class 2'; -- 標準的な OLAP クエリ
次の図は、そのプロセスを示しています。
利用例
以下の例は、異なるストレージフォーマットのテーブルを作成する方法を示しています。
Hologres V2.1 以降の構文:
-- 行指向テーブルの作成 CREATE TABLE public.tbl_row ( a INTEGER NOT NULL, b TEXT NOT NULL, PRIMARY KEY (a) ) WITH ( orientation = 'row' ); -- 列指向テーブルの作成 CREATE TABLE tbl_col ( a INT NOT NULL, b TEXT NOT NULL ) WITH ( orientation = 'column' ); -- 行列ハイブリッドテーブルの作成 CREATE TABLE tbl_col_row ( pk TEXT NOT NULL, col1 TEXT, col2 TEXT, col3 TEXT, PRIMARY KEY (pk) ) WITH ( orientation = 'row,column' );すべてのバージョンの構文:
-- 行指向テーブルの作成 BEGIN; CREATE TABLE public.tbl_row ( a INTEGER NOT NULL, b TEXT NOT NULL, PRIMARY KEY (a) ); CALL set_table_property('public.tbl_row', 'orientation', 'row'); COMMIT; -- 列指向テーブルの作成 BEGIN; CREATE TABLE tbl_col ( a INT NOT NULL, b TEXT NOT NULL); CALL set_table_property('tbl_col', 'orientation', 'column'); COMMIT; -- 行列ハイブリッドテーブルの作成 BEGIN; CREATE TABLE tbl_col_row ( pk TEXT NOT NULL, col1 TEXT, col2 TEXT, col3 TEXT, PRIMARY KEY (pk)); CALL set_table_property('tbl_col_row', 'orientation', 'row,column'); COMMIT;
参考資料
ビジネス クエリ シナリオに基づくテーブルプロパティの設定については、「シナリオに基づくテーブル作成およびチューニングガイド」をご参照ください。