基本概念
このドキュメントでは、主にDorisでのテーブル作成とデータパーティショニング、およびテーブル作成操作で発生する可能性がある問題と解決策について説明します。
Row & Column
Dorisでは、データはテーブルの形で論理的に記述されます。
テーブルは行と列で構成されます:
-
Row:ユーザーデータの1行を表します;
-
Column:1行のデータ内の異なるフィールドを記述するために使用されます;
-
列は2つのタイプに分けることができます:KeyとValue。ビジネスの観点から、KeyとValueはそれぞれディメンション列とメトリック列に対応できます。Apache Dorisのkey列は、テーブル作成文で指定されるもので、キーワード
unique key、aggregate key、またはduplicate keyに続く列です。残りの列はvalue列です。集約モデルの観点から、同じKey列を持つ行は1つの行に集約されます。value列の集約方法は、テーブル作成時にユーザーが指定します。集約モデルの詳細については、Doris Data Modelを参照してください。
パーティション & バケット
Dorisは2レベルのパーティショニングとバケッティング手法を使用してデータを整理および管理します。
パーティション
パーティションとは、テーブル内の特定の列値に基づいて、テーブルをより小さく、より管理しやすく、重複のないサブセットに分割することを指します。各データのサブセットをパーティションと呼びます。各行のデータは、正確に1つの特定のパーティションに属します。パーティションは最小の論理管理単位と見なすことができます。
現在、Dorisは2つのタイプのパーティショニングをサポートしています:RangeとList。テーブル作成時にパーティションが指定されていない場合、Dorisはテーブル内のすべてのデータを含むデフォルトパーティションを生成し、これはユーザーには透明です。
データ分散とクエリパターンに基づくパーティショニングには、いくつかの利点があります:
-
クエリパフォーマンスの向上:パーティショニングにより、システムはクエリ条件に基づいて無関係なパーティションを除外でき、スキャンするデータ量を減らし、クエリ効率を大幅に向上させます。これは大規模データセットを扱う際に特に有益で、パーティション戦略はI/Oオーバーヘッドを大幅に削減できます。
-
柔軟な管理:パーティショニングにより、時間や地理などのロジックに基づいてデータを分割でき、データのアーカイブ、クリーニング、バックアップが容易になります。例えば、時間によるパーティショニングは履歴データと新規追加データを効果的に管理でき、効率的な時間ベースのデータメンテナンス戦略をサポートします。
バケット
Bucketingとは、パーティション内のデータを何らかのルールに従ってさらに小さく、重複のない単位に分割することを指します。各行のデータは、正確に1つの特定のバケットに属します。特定の列値に基づいてデータを分割するパーティショニングとは異なり、バケッティングは事前定義されたバケット全体にデータを均等に分散しようとし、それによってデータスキューを減らします。バケッティングは、均等なデータ分散を確保し、データローカリティを向上させることで、クエリパフォーマンスを向上させます。
現在、Dorisは2つのタイプのバケッティングをサポートしています:HashとRandom。
バケットは物理レベルでデータシャード(Tablet)に対応し、データシャードは物理的に独立して保存されます。これらは、データ移動やレプリケーションなどの操作における最小の物理ストレージ単位です。
適切なバケッティングには、いくつかの利点があります:
-
均等なデータ分散:バケッティングはバケット全体にデータを均等に分散し、データ集中やスキューのリスクを減らし、特定のノードやストレージデバイスでのリソースオーバーロードを防ぎます。
-
ホットスポットの削減:データを均等に分散することで、バケッティングは特定のノードやパーティションのオーバーロードのリスクを軽減し、ホットスポットを防ぎ、システムの安定性と処理能力を向上させます。
-
並行パフォーマンスの向上:バケッティングは並行クエリのパフォーマンスを向上させ、特に複数のクエリリクエストが同じパーティション内の異なるデータにアクセスする必要がある場合に効果的です。バケッティングの粒度により、システムは複数のリクエストを並列で効率的に処理でき、それによってスループットを向上させます。
テーブル作成の例
Apache DorisでのCREATE TABLEは同期コマンドで、SQLが実行されると結果を返します。成功した戻り値はテーブル作成が成功したことを示します。詳細については、CREATE-TABLEを参照するか、HELP CREATE TABLEコマンドを入力してください。
以下のコードサンプルでは、RANGEパーティショニングとHashバケットを使用してApache Dorisでテーブルを作成する方法を紹介します。
-- Range Partition
CREATE TABLE IF NOT EXISTS example_range_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "User ID",
`date` DATE NOT NULL COMMENT "Date when the data are imported",
`timestamp` DATETIME NOT NULL COMMENT "Timestamp when the data are imported",
`city` VARCHAR(20) COMMENT "User location city",
`age` SMALLINT COMMENT "User age",
`sex` TINYINT COMMENT "User gender",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User last visit time",
`cost` BIGINT SUM DEFAULT "0" COMMENT "Total user consumption",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time"
)
ENGINE=OLAP
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
PARTITION BY RANGE(`date`)
(
PARTITION `p201701` VALUES [("2017-01-01"), ("2017-02-01")),
PARTITION `p201702` VALUES [("2017-02-01"), ("2017-03-01")),
PARTITION `p201703` VALUES [("2017-03-01"), ("2017-04-01"))
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
"replication_num" = "1"
);
ここではAggregate Key Modelを例として使用します。Aggregate Key Modelでは、集約タイプ(SUM、REPLACE、MAX、MIN)で指定されたすべての列がValue列になります。残りの列はKey列です。
CREATE TABLEのPROPERTIESセクションで設定できるフィールドについての詳細情報は、CREATE-TABLEを参照してください。
ENGINEのデフォルトタイプはOLAPです。OLAPのみがApache Doris自体によるデータ管理と保存を担当します。MySQL、Broker、ESなどの他のエンジンタイプは、本質的には他の外部データベースやシステム内のテーブルへのマッピングに過ぎず、Apache Dorisがこのデータを読み取れるようにします。しかし、Apache Doris自体はOLAP以外のエンジンタイプについては、テーブルやデータの作成、管理、保存を行いません。
IF NOT EXISTSは、テーブルが以前に作成されていない場合に作成されることを示します。これはテーブル名が存在するかどうかのみをチェックし、新しいテーブルのスキーマが既存のテーブルのスキーマと同じかどうかはチェックしないことに注意してください。したがって、同じ名前だが異なるスキーマのテーブルが存在する場合でも、このコマンドは成功を返しますが、新しいスキーマを持つ新しいテーブルが作成されたことを意味するものではありません。
高度な機能と例
DorisはDynamic パーティション、Auto パーティション、Auto バケットなどの高度なデータパーティション方法をサポートしており、より柔軟なデータ管理を可能にします。以下は実装例です: より便利です。上記の例をAuto Range パーティションで以下のように書き換えます:
- Auto Partition
- Dynamic Partition
- Auto&Dynamic Partition
- Auto Bucket
Auto パーティションは、データインポート時にユーザー定義のルールに従って対応するパーティションの自動作成をサポートします。
CREATE TABLE IF NOT EXISTS example_range_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "User ID",
`date` DATE NOT NULL COMMENT "Date when the data are imported",
`timestamp` DATETIME NOT NULL COMMENT "Timestamp when the data are imported",
`city` VARCHAR(20) COMMENT "User location city",
`age` SMALLINT COMMENT "User age",
`sex` TINYINT COMMENT "User gender",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User last visit time",
`cost` BIGINT SUM DEFAULT "0" COMMENT "Total user consumption",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time"
)
ENGINE=OLAP
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
AUTO PARTITION BY RANGE(date_trunc(`date`, 'month')) --- Using months as partition granularity
()
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
"replication_num" = "1"
);
上記のように、データがインポートされると、DorisはmonthレベルのgranularityでDATEに対応するpartitionを自動的に作成します。2018-12-01と2018-12-31は同じpartitionに含まれ、2018-11-12は前のpartitionに含まれます。Auto パーティションはList partitionもサポートしています。詳しい使用方法については、Auto パーティションのドキュメントを確認してください。
Dynamic パーティションは、リアルタイムに基づく自動的なpartition作成および回復管理方法です。上記の例をdynamic partitioningで書き直すと以下のようになります:
CREATE TABLE IF NOT EXISTS example_range_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "User ID",
`date` DATE NOT NULL COMMENT "Date when the data are imported",
`timestamp` DATETIME NOT NULL COMMENT "Timestamp when the data are imported",
`city` VARCHAR(20) COMMENT "User location city",
`age` SMALLINT COMMENT "User age",
`sex` TINYINT COMMENT "User gender",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User last visit time",
`cost` BIGINT SUM DEFAULT "0" COMMENT "Total user consumption",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time"
)
ENGINE=OLAP
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
PARTITION BY RANGE(`date`)
()
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
"replication_num" = "1",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "WEEK", --- Partition granularity is week
"dynamic_partition.start" = "-2", --- Retain two weeks forward
"dynamic_partition.end" = "2", --- Two weeks after creation in advance
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "8"
);
動的パーティションは階層ストレージ、カスタマイズされたコピー数、その他の機能をサポートしています。詳細については動的パーティションのドキュメントを参照してください。
Doris 2.1.7以降でサポート
Auto パーティションとDynamic パーティションはそれぞれ独自の利点があり、この2つを組み合わせることで、柔軟なオンデマンドパーティション作成と自動回収が可能になります:
CREATE TABLE IF NOT EXISTS example_range_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "User ID",
`date` DATE NOT NULL COMMENT "Date when the data are imported",
`timestamp` DATETIME NOT NULL COMMENT "Timestamp when the data are imported",
`city` VARCHAR(20) COMMENT "User location city",
`age` SMALLINT COMMENT "User age",
`sex` TINYINT COMMENT "User gender",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User last visit time",
`cost` BIGINT SUM DEFAULT "0" COMMENT "Total user consumption",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time"
)
ENGINE=OLAP
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
AUTO PARTITION BY RANGE(date_trunc(`date`, 'month')) --- Using months as partition granularity
()
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
"replication_num" = "1",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "month", --- Both must have the same granularity
"dynamic_partition.start" = "-2", --- Dynamic Partition automatically cleans up partitions that are more than two weeks old
"dynamic_partition.end" = "0", --- Dynamic Partition does not create future partitions. it is left entirely to Auto Partition.
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "8"
);
この機能に関する詳細な提案については、Auto パーティション Conjunct with Dynamic パーティションを参照してください。
ユーザーが適切なバケット数が分からない場合、Auto バケットによってDorisが推定を完了し、ユーザーはテーブルデータの推定量を提供するだけで済みます:
CREATE TABLE IF NOT EXISTS example_range_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "User ID",
`date` DATE NOT NULL COMMENT "Date when the data are imported",
`timestamp` DATETIME NOT NULL COMMENT "Timestamp when the data are imported",
`city` VARCHAR(20) COMMENT "User location city",
`age` SMALLINT COMMENT "User age",
`sex` TINYINT COMMENT "User gender",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User last visit time",
`cost` BIGINT SUM DEFAULT "0" COMMENT "Total user consumption",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time"
)
ENGINE=OLAP
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
PARTITION BY RANGE(`date`)
(
PARTITION `p201701` VALUES LESS THAN ("2017-02-01"),
PARTITION `p201702` VALUES LESS THAN ("2017-03-01"),
PARTITION `p201703` VALUES LESS THAN ("2017-04-01"),
PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01"))
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS AUTO
PROPERTIES
(
"replication_num" = "1",
"estimate_partition_size" = "2G" --- User estimate of the amount of data a partition will have, defaults to 10G if not provided
);
このアプローチは、テーブルデータの量が特に大きい場合には適用されないことに注意してください。
パーティションの表示
show create tableコマンドを実行して、テーブルのパーティション情報を表示します。
> show create table example_range_tbl
+-------------------+---------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------------+---------------------------------------------------------------------------------------------------------+
| example_range_tbl | CREATE TABLE `example_range_tbl` ( |
| | `user_id` largeint(40) NOT NULL COMMENT 'User ID', |
| | `date` date NOT NULL COMMENT 'Date when the data are imported', |
| | `timestamp` datetime NOT NULL COMMENT 'Timestamp when the data are imported', |
| | `city` varchar(20) NULL COMMENT 'User location city', |
| | `age` smallint(6) NULL COMMENT 'User age', |
| | `sex` tinyint(4) NULL COMMENT 'User gender', |
| | `last_visit_date` datetime REPLACE NULL DEFAULT "1970-01-01 00:00:00" COMMENT 'User last visit time', |
| | `cost` bigint(20) SUM NULL DEFAULT "0" COMMENT 'Total user consumption', |
| | `max_dwell_time` int(11) MAX NULL DEFAULT "0" COMMENT 'Maximum user dwell time', |
| | `min_dwell_time` int(11) MIN NULL DEFAULT "99999" COMMENT 'Minimum user dwell time' |
| | ) ENGINE=OLAP |
| | AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) |
| | COMMENT 'OLAP' |
| | PARTITION BY RANGE(`date`) |
| | (PARTITION p201701 VALUES [('0000-01-01'), ('2017-02-01')), |
| | PARTITION p201702 VALUES [('2017-02-01'), ('2017-03-01')), |
| | PARTITION p201703 VALUES [('2017-03-01'), ('2017-04-01'))) |
| | DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 |
| | PROPERTIES ( |
| | "replication_allocation" = "tag.location.default: 1", |
| | "is_being_synced" = "false", |
| | "storage_format" = "V2", |
| | "light_schema_change" = "true", |
| | "disable_auto_compaction" = "false", |
| | "enable_single_replica_compaction" = "false" |
| | ); |
+-------------------+---------------------------------------------------------------------------------------------------------+
またはshow partitions from your_tableコマンドを実行してください。
> show partitions from example_range_tbl
+-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------
+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium
| CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable |
+-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------
+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
| 28731 | p201701 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [0000-01-01]; ..types: [DATEV2]; keys: [2017-02-01]; ) | user_id | 16 | 1 | HDD
| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true |
| 28732 | p201702 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [2017-02-01]; ..types: [DATEV2]; keys: [2017-03-01]; ) | user_id | 16 | 1 | HDD
| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true |
| 28733 | p201703 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [2017-03-01]; ..types: [DATEV2]; keys: [2017-04-01]; ) | user_id | 16 | 1 | HDD
| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true |
+-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------
+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
パーティションの変更
alter table add partition コマンドを実行することで、新しいパーティションを追加できます。
ALTER TABLE example_range_tbl ADD PARTITION p201704 VALUES LESS THAN("2020-05-01") DISTRIBUTED BY HASH(`user_id`) BUCKETS 5;
パーティションの変更方法の詳細については、ALTER-TABLE-PARTITIONを参照してください。
パーティション Retrieval
partitionsテーブル関数(2.1.5以降でサポート)とinformation_schema.partitionsシステムテーブル(2.1.7以降でサポート)は、クラスターのパーティション情報を記録します。パーティションを自動管理する際に使用するため、対応するテーブルからパーティション情報を抽出できます:
--- Find the partition with the corresponding value in the Auto Partition table.
mysql> select * from partitions("catalog"="internal", "database"="optest", "table"="DAILY_TRADE_VALUE") where PartitionName = auto_partition_name('range', 'year', '2008-02-03');
+-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
+-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
| 127095 | p20080101000000 | 2 | 2024-11-14 17:29:02 | NORMAL | TRADE_DATE | [types: [DATEV2]; keys: [2008-01-01]; ..types: [DATEV2]; keys: [2009-01-01]; ) | TRADE_DATE | 10 | 1 | HDD | 9999-12-31 23:59:59 | | \N | 985.000 B | 0 | tag.location.default: 1 | 1 | 1 | \N |
+-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
1 row in set (0.30 sec)
mysql> select * from information_schema.partitions where TABLE_SCHEMA='optest' and TABLE_NAME='list_table1' and PARTITION_NAME=auto_partition_name('list', null);
+---------------+--------------+-------------+----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+-----------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | SUBPARTITION_NAME | PARTITION_ORDINAL_POSITION | SUBPARTITION_ORDINAL_POSITION | PARTITION_METHOD | SUBPARTITION_METHOD | PARTITION_EXPRESSION | SUBPARTITION_EXPRESSION | PARTITION_DESCRIPTION | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | CREATE_TIME | UPDATE_TIME | CHECK_TIME | CHECKSUM | PARTITION_COMMENT | NODEGROUP | TABLESPACE_NAME |
+---------------+--------------+-------------+----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+-----------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
| internal | optest | list_table1 | pX | NULL | 0 | 0 | LIST | NULL | str | NULL | (NULL) | 1 | 1266 | 1266 | 0 | 0 | 0 | 0 | 2024-11-14 19:58:45 | 0000-00-00 00:00:00 | 0 | | | |
+---------------+--------------+-------------+----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+-----------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
1 row in set (0.24 sec)
--- Find the partition that corresponds to the starting point
mysql> select * from information_schema.partitions where TABLE_NAME='DAILY_TRADE_VALUE' and PARTITION_DESCRIPTION like "[('2012-01-01'),%";
+---------------+--------------+-------------------+-----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+----------------------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | SUBPARTITION_NAME | PARTITION_ORDINAL_POSITION | SUBPARTITION_ORDINAL_POSITION | PARTITION_METHOD | SUBPARTITION_METHOD | PARTITION_EXPRESSION | SUBPARTITION_EXPRESSION | PARTITION_DESCRIPTION | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | CREATE_TIME | UPDATE_TIME | CHECK_TIME | CHECKSUM | PARTITION_COMMENT | NODEGROUP | TABLESPACE_NAME |
+---------------+--------------+-------------------+-----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+----------------------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
| internal | optest | DAILY_TRADE_VALUE | p20120101000000 | NULL | 0 | 0 | RANGE | NULL | TRADE_DATE | NULL | [('2012-01-01'), ('2013-01-01')) | 1 | 985 | 985 | 0 | 0 | 0 | 0 | 2024-11-14 17:29:02 | 0000-00-00 00:00:00 | 0 | | | |
+---------------+--------------+-------------------+-----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+----------------------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
1 row in set (0.65 sec)