ハイブリッド行列ストレージ
Hybrid Row-Columnar Storage
Dorisはデフォルトでカラムナストレージを使用し、各カラムは連続して格納されます。カラムナストレージは分析シナリオ(集計、フィルタリング、ソートなど)において優れたパフォーマンスを提供します。必要なカラムのみを読み取るため、不要なIOを削減できるからです。しかし、ポイントクエリシナリオ(SELECT *など)では、すべてのカラムを読み取る必要があり、各カラムに対してIO操作が必要となるため、IOPSがボトルネックとなる可能性があります。特に多数のカラムを持つワイドTable(例:数百のカラム)においてその傾向が顕著です。
ポイントクエリシナリオにおけるIOPSボトルネックに対処するため、バージョン2.0.0以降、DorisはHybrid Row-Columnar Storageをサポートしています。ユーザーがTableを作成する際に、行ストレージを有効にするかどうかを指定できます。行ストレージが有効になっている場合、ポイントクエリ(SELECT *など)では各行に対して1回のIO操作のみが必要となり、パフォーマンスが大幅に向上します。
行ストレージの原理は、ストレージ時に追加のカラムが追加されることです。このカラムは対応する行のすべてのカラムを連結し、特別なバイナリ形式を使用して格納します。
Syntax
Table作成時に、TableのPROPERTIESで行ストレージを有効にするかどうか、どのカラムに対して行ストレージを有効にするか、ストレージ圧縮単位サイズpage_sizeを指定します。
- 行ストレージを有効にするかどうか:デフォルトはfalse(無効)です。
"store_row_column" = "true"
- 行ストレージを有効にする列:
"store_row_column" = "true"の場合、デフォルトですべての列が有効になります。一部の列のみ行ストレージを有効にする必要がある場合は、row_store_columnsパラメータ(バージョン3.0以降)を設定し、列名をカンマ区切りのリスト形式で指定します。
"row_store_columns" = "column1,column2,column3"
- 行ストレージのpage_size: デフォルトは16KBです。
"row_store_page_size" = "16384"
ページは、ストレージの読み取りおよび書き込み操作の最小単位であり、page_sizeは行ストアページのサイズを指します。これは、単一の行を読み取るためにページIOを生成する必要があることを意味します。この値が大きいほど、圧縮効果が向上し、ストレージ空間の使用量が少なくなります。しかし、ポイントクエリ時のIOオーバーヘッドが増加し、パフォーマンスが低下します(各IO操作は少なくとも1ページを読み取るため)。逆に、値が小さいほど、ストレージ空間の使用量が多くなり、ポイントクエリのパフォーマンスが向上します。デフォルト値の16KBは、ほとんどの場合においてバランスの取れた選択です。クエリパフォーマンスを優先する場合は、4KBまたはそれ以下のより小さい値を設定できます。ストレージ空間を優先する場合は、64KBまたはそれ以上のより大きい値を設定できます。
Row Store ヒット条件
Row storeヒット条件は2つのシナリオに分かれます:1つは、Table属性に依存しポイントクエリ条件を満たす高同時実行プライマリキーポイントクエリ、もう1つは単一TableのSELECT *クエリです。これら2つのクエリタイプについて以下で説明します。
-
高同時実行プライマリキーポイントクエリの場合、Table属性に
"enable_unique_key_merge_on_write" = "true"(MOWTable)および"store_row_column" = "true"(すべての列がrow storeに個別に格納され、比較的高いストレージコストが発生)または"row_store_columns" = "key,v1,v3,v5,v7"(指定された列のみがrow storeに格納される)が必要です。クエリ時には、WHERE句にすべてのプライマリキーがANDで接続された等価条件で含まれることを確認してください。例:SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2または特定の列をクエリするSELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2。row storeに一部の列のみが含まれている場合(例:v1)で、クエリ対象の列(例:v2)がrow storeにない場合、残りの列はcolumn storeからクエリされます。この例では、v1はrow storeからクエリされ、v2はcolumn store(より大きなページサイズを持ち、より多くの読み取り増幅を引き起こす)からクエリされます。EXPLAINを使用して高同時実行プライマリキーポイントクエリ最適化がヒットしているかを確認できます。ポイントクエリの使用方法の詳細については、High-Concurrency Point Queryを参照してください。 -
一般的な非プライマリキーポイントクエリの場合、row storeを利用するには、Tableモデルが
DUPLICATEであるか、"enable_unique_key_merge_on_write" = "true"(MOWTable)および"store_row_column" = "true"(すべての列がrow storeに個別に格納され、比較的高いストレージコストが発生)である必要があります。このパターンを満たすクエリは、SELECT * FROM tbl [WHERE XXXXX] ORDER BY XXX LIMIT Nでrow storeをヒットできます。ここで、角括弧内のコンテンツはオプションのクエリ条件です。現在、SELECT *のみがサポートされており、TOPN遅延マテリアライゼーション最適化をヒットする必要があることに注意してください。詳細については、TOPN Query 最適化を参照してください。つまり、OPT TWO PHASEをヒットする必要があります。最後に、EXPLAINを使用してFETCH ROW STOREマーカーを確認し、row storeヒットを確認してください。
使用例
以下の例では、8つの列を持つTableを作成し、そのうち5つの列key, v1, v3, v5, v7がrow storeに対して有効化され、高同時実行ポイントクエリパフォーマンスのためにpage_sizeが4KBに設定されています。
CREATE TABLE `tbl_point_query` (
`k` int(11) NULL,
`v1` decimal(27, 9) NULL,
`v2` varchar(30) NULL,
`v3` varchar(30) NULL,
`v4` date NULL,
`v5` datetime NULL,
`v6` float NULL,
`v7` datev2 NULL
) ENGINE=OLAP
UNIQUE KEY(`k`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
"row_store_columns" = "k,v1,v3,v5,v7",
"row_store_page_size" = "4096"
);
Query 1
SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
上記のステートメントのEXPLAIN出力には、SHORT-CIRCUITマーカーが含まれている必要があります。ポイントクエリの使用方法の詳細については、High-Concurrency Point Queryを参照してください。
以下の例では、DUPLICATETableが行ストアクエリの条件を満たす方法を示します。
CREATE TABLE `tbl_duplicate` (
`k` int(11) NULL,
`v1` string NULw
) ENGINE=OLAP
DUPLICATE KEY(`k`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"light_schema_change" = "true",
"store_row_column" = "true",
"row_store_page_size" = "4096"
);
"store_row_column" = "true" が必要です。
クエリ 2(注意:TOPN クエリ最適化にヒットする必要があり、SELECT * である必要があります)
SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
上記のステートメントのEXPLAIN出力には、FETCH ROW STOREマーカーとOPT TWO PHASEマーカーが含まれるはずです。
注意
- 行ストレージを有効にすると、使用されるストレージ容量が増加します。ストレージ容量の増加はデータの特性に関連しており、一般的に元のTableのサイズの2倍から10倍になります。正確な容量使用量は、実際のデータでテストする必要があります。
- 行ストレージの
page_sizeもストレージ容量に影響します。以前のTable属性パラメータrow_store_page_sizeに基づいて調整できます。