表达式分区(推荐)
自 v3.0 起,StarRocks 支持表达式分区(原称自动创建分区),更加灵活易用,适用于大多数场景,比如按照连续日期范围或者枚举值来查询和管理数据。
您仅需要在建表时设置 分区表达式(时间函数表达式或列表达式)。在数据导入时,StarRocks 会根据数据和分区表达式的定义规则自动创建分区,您无需在建表时预先手动/批量创建大量分区,或者配置动态分区属性。
时间函数表达式分区
如果您经常按照连续日期范围来查询和管理数据,则只需要在时间函数分区表达式中,指定一个日期类型(DATE 或者 DATETIME )的分区列,以及指定分区粒度(年、月、日或小时)。StarRocks 会根据导入的数据和分区表达式,自动创建分区并且设置分区的起止时间。
不过在一些特殊场景下,比如历史数据按月划分分区、最近数据按天划分分区,则需要采用 Range 分区创建分区。
语法
PARTITION BY expression
...
[ PROPERTIES( 'partition_live_number' = 'xxx' ) ]
expression ::=
{ date_trunc ( <time_unit> , <partition_column> ) |
time_slice ( <partition_column> , INTERVAL <N> <time_unit> [ , boundary ] ) }
参数解释
参数 | 是否必填 | 说明 |
---|---|---|
expression | 是 | 目前仅支持 date_trunc 和 time_slice 函数。并且如果您使用 time_slice 函数,则可以不传入参数 boundary ,因为在该场景中该参数默认且仅支持为 floor ,不支持为 ceil 。 |
time_unit | 是 | 分区粒度,目前仅支持为 hour 、day 、month 或 year ,暂时不支持为 week 。如果分区粒度为 hour ,则仅支持分区列为 DATETIME 类型,不支持为 DATE 类型。 |
partition_column | 是 | 分区列。
|
partition_live_number | 否 | 保留最近多少数量的分区。最近是指分区按时间的先后顺序进行排 序,以当前时间为基准,然后从后往前数指定个数的分区进行保留,其余(更早的)分区会被删除。后台会定时调度任务来管理分区数量,调度间隔可以通过 FE 动态参数 dynamic_partition_check_interval_seconds 配置,默认为 600 秒,即 10 分钟。假设当前为 2023 年 4 月 4 日,partition_live_number 设置为 2 ,分区包含 p20230401 、p20230402 、p20230403 、p20230404 ,则分区 p20230403 、p20230404 会保留,其他分区会删除。如果导入了脏数据,比如未来时间 4 月 5 日和 6 日的数据,导致分区包含 p20230401 、p20230402 、p20230403 、p20230404 、p20230405 、p20230406 ,则分区 p20230403 、p20230404 、p20230405 、p20230406 会保留,其他分区会删除。 |
使用说明
- 在导入的过程中 StarRocks 根据导入数据已经自动创建了一些分区,但是由于某些原因导入作业最终失败,则在当前版本中,已经自动创建的分区并不会由于导入失败而自动删除。
- StarRocks 自动创建分区数量上限默认为 4096,由 FE 配置参数
max_automatic_partition_number
决定。该参数可以防止您由于误操作而创建大量分区。 - 分区命名规则与动态分区的命名规则一致。
示例
示例一:假设您经常按天查询数据,则建表时可以 使用分区表达式 date_trunc()
,并且设置分区列为 event_day
,分区粒度为 day
,实现导入数据时自动按照数据所属日期划分分区。将同一天的数据存储在一个分区中,利用分区裁剪可以显著提高查询效率。
CREATE TABLE site_access1 (
event_day DATETIME NOT NULL,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY date_trunc('day', event_day)
DISTRIBUTED BY HASH(event_day, site_id);
导入如下两行数据,则 StarRocks 会根据导入数据的日期范围自动创建两个分区 p20230226
、p20230227
,范围分别为 [2023-02-26 00:00:00,2023-02-27 00:00:00)、[2023-02-27 00:00:00,2023-02-28 00:00:00)。如果后续导入数据的日期属于这两个范围,则都会自动划分至对应分区。
-- 导入两行数据
INSERT INTO site_access1
VALUES ("2023-02-26 20:12:04",002,"New York","Sam Smith",1),
("2023-02-27 21:06:54",001,"Los Angeles","Taylor Swift",1);
-- 查询分区
mysql > SHOW PARTITIONS FROM site_access1;
+-------------+---------------+----------------+---------------------+--------------------+--------+--------------+------------------------------------------------------------------------------------------------------+--------------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | VisibleVersionHash | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | LastConsistencyCheckTime | DataSize | IsInMemory | RowCount |
+-------------+---------------+----------------+---------------------+--------------------+--------+--------------+------------------------------------------------------------------------------------------------------+--------------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
| 17138 | p20230226 | 2 | 2023-07-19 17:53:59 | 0 | NORMAL | event_day | [types: [DATETIME]; keys: [2023-02-26 00:00:00]; ..types: [DATETIME]; keys: [2023-02-27 00:00:00]; ) | event_day, site_id | 6 | 3 | HDD | 9999-12-31 23:59:59 | NULL | 0B | false | 0 |
| 17113 | p20230227 | 2 | 2023-07-19 17:53:59 | 0 | NORMAL | event_day | [types: [DATETIME]; keys: [2023-02-27 00:00:00]; ..types: [DATETIME]; keys: [2023-02-28 00:00:00]; ) | event_day, site_id | 6 | 3 | HDD | 9999-12-31 23:59:59 | NULL | 0B | false | 0 |
+-------------+---------------+----------------+---------------------+--------------------+--------+--------------+------------------------------------------------------------------------------------------------------+--------------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
2 rows in set (0.00 sec)
示例二:如果您希望引入分区生命周期管理,即仅保留最近一段时间的分区,删除历史分区,则可以使用 partition_live_number
设置只保留最近多少数量的分区。
CREATE TABLE site_access2 (
event_day DATETIME NOT NULL,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY date_trunc('month', event_day)
DISTRIBUTED BY HASH(event_day, site_id)
PROPERTIES(
"partition_live_number" = "3" -- 只保留最近 3 个分区
);
示例三:假设您经常按周查询数据,则建表时可以使用分区表达式 time_slice()
,设置分区列为 event_day
,分区粒度为七天。将一周的数据存储在一个分区中,利用分区裁剪可以显著提高查询效率。
CREATE TABLE site_access3 (
event_day DATETIME NOT NULL,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY time_slice(event_day, INTERVAL 7 day)
DISTRIBUTED BY HASH(event_day, site_id);