生成列
バージョン v3.1 以降、StarRocks は生成列をサポートしています。生成列は、複雑な式を含むクエリを高速化するために使用できます。この機能は、式の結果を事前に計算して保存し、クエリの書き換えをサポートすることで、同じ複雑な式を含むクエリを大幅に高速化します。
テーブル作成時に、式の結果を保存するための生成列を1つ以上定義できます。そのため、定義した生成列に結果が保存さ れている式を含むクエリを実行する際、CBO はクエリを生成列から直接データを読み取るように書き換えます。あるいは、生成列のデータを直接クエリすることもできます。
また、生成列がロードパフォーマンスに与える影響を評価することをお勧めします。なぜなら、式の計算には時間がかかるからです。さらに、テーブル作成時に生成列を作成することをお勧めします。なぜなら、テーブル作成後に生成列を追加または変更するのは時間とコストがかかるからです。
ただし、生成列を持つテーブルにデータをロードする際、StarRocks は式に基づいて結果を計算し、生成列に結果を書き込むため、時間とオーバーヘッドが増加する可能性があることに注意してください。
現在、StarRocks の共有データモードは生成列をサポートしていません。
基本操作
生成列の作成
構文
<col_name> <data_type> [NULL] AS <expr> [COMMENT 'string']
テーブル作成時に生成列を作成
test_tbl1
という名前のテーブルを作成し、5つの列を持ち、そのうち newcol1
と newcol2
は生成列であり、指定された式を使用して通常の列 data_array
と data_json
の値を参照して計算されます。
CREATE TABLE test_tbl1
(
id INT NOT NULL,
data_array ARRAY<int> NOT NULL,
data_json JSON NOT NULL,
newcol1 DOUBLE AS array_avg(data_array),
newcol2 String AS json_string(json_query(data_json, "$.a"))
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id);
注意:
- 生成列は通常の列の後に定義する必要があります。
- 集計関数は生成列の式で使用できません。
- 生成列の式は他の生成列や自動インクリメント列を参照できませんが、複数の通常の列を参照することはできます。
- 生成列のデータ型は、生成列の式によって生成される結果のデータ型と一致している必要があります。
- 集計テーブルに生成列を作成することはできません。
テーブル作成後に生成列を追加
ほとんどの場合、クエリ時に頻繁に使用される式はテーブル作成後に決定されるため、生成列はテーブル作成後に追加されることが多いです。パフォーマンスの観点から、StarRocks がテーブル作成後に生成列を追加するための基盤となるロジックは最適化されています。そのため、生成列を追加する際、StarRocks はすべてのデータを書き換える必要はありません。代わりに、StarRocks は新たに追加された生成列のデータを書き込み、そのデータを既存の物理データファイルと関連付けるだけで済みます。これにより、テーブル作成後に生成列を追加する効率が大幅に向上します。
-
id
、data_array
、data_json
の3つの通常の列を持つtest_tbl2
という名前のテーブルを作成し、データ行を挿入します。-- テーブルを作成
CREATE TABLE test_tbl2
(
id INT NOT NULL,
data_array ARRAY<int> NOT NULL,
data_json JSON NOT NULL
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id);
-- データ行を挿入
INSERT INTO test_tbl2 VALUES (1, [1,2], parse_json('{"a" : 1, "b" : 2}'));
-- テーブルをク エリ
MySQL [example_db]> select * from test_tbl2;
+------+------------+------------------+
| id | data_array | data_json |
+------+------------+------------------+
| 1 | [1,2] | {"a": 1, "b": 2} |
+------+------------+------------------+
1 row in set (0.04 sec) -
ALTER TABLE ... ADD COLUMN ...
を実行して、通常の列data_array
とdata_json
の値に基づいて評価された式によって作成された生成列newcol1
とnewcol2
を追加します。ALTER TABLE test_tbl2
ADD COLUMN newcol1 DOUBLE AS array_avg(data_array);
ALTER TABLE test_tbl2
ADD COLUMN newcol2 String AS json_string(json_query(data_json, "$.a"));注意:
- 集計テーブルに生成列を追加することはサポートされていません。
- 通常の列は生成列の前に定義する必要があります。
ALTER TABLE ... ADD COLUMN ...
ステートメントを使用して通常の列を追加する際に、新しい通常の列の位置を指定しない場合、システムは自動的にそれを生成列の前に配置します。さらに、AFTER を使用して通常の列を生成列の後に明示的に配置することはできません。
-
テーブルデータをクエリします。
MySQL [example_db]> SELECT * FROM test_tbl2;
+------+------------+------------------+---------+---------+
| id | data_array | data_json | newcol1 | newcol2 |
+------+------------+------------------+---------+---------+
| 1 | [1,2] | {"a": 1, "b": 2} | 1.5 | 1 |
+------+------------+------------------+---------+---------+
1 row in set (0.04 sec)結果は、生成列
newcol1
とnewcol2
がテーブルに追加され、StarRocks が式に基づいてその値を自動的に計算することを示しています。
生成列へのデータロード
データロード中、StarRocks は式に基づいて生成列の値を自動的に計算します。生成列の値を指定することはできません。以下の例では、INSERT INTO ステートメントを使用してデータをロードします。
-
INSERT INTO
を使用してtest_tbl1
テーブルにレコードを挿入します。VALUES ()
句内で生成列の値を指定することはできません。INSERT INTO test_tbl1 (id, data_array, data_json)
VALUES (1, [1,2], parse_json('{"a" : 1, "b" : 2}')); -
テーブルデータをクエリします。
MySQL [example_db]> SELECT * FROM test_tbl1;
+------+------------+------------------+---------+---------+
| id | data_array | data_json | newcol1 | newcol2 |
+------+------------+------------------+---------+---------+
| 1 | [1,2] | {"a": 1, "b": 2} | 1.5 | 1 |
+------+------------+------------------+---------+---------+
1 row in set (0.01 sec)結果は、StarRocks が式に基づいて生成列
newcol1
とnewcol2
の値を自動的に計算することを示しています。注意:
データロード中に生成列の値を指定すると、次のエラーが返されます。
MySQL [example_db]> INSERT INTO test_tbl1 (id, data_array, data_json, newcol1, newcol2)
VALUES (2, [3,4], parse_json('{"a" : 3, "b" : 4}'), 3.5, "3");
ERROR 1064 (HY000): Getting analyzing error. Detail message: materialized column 'newcol1' can not be specified.
MySQL [example_db]> INSERT INTO test_tbl1 VALUES (2, [3,4], parse_json('{"a" : 3, "b" : 4}'), 3.5, "3");
ERROR 1064 (HY000): Getting analyzing error. Detail message: Column count doesn't match value count.