1. List 分区示例:按地区划分数据
List 分区适合取值集合明确、离散的字段,例如地区、业务线、租户类型等。与 Range 分区按连续区间切分不同,List 分区通过枚举值精确匹配,只有命中枚举值的数据才能写入对应分区。
sql
CREATE TABLE IF NOT EXISTS demo.user_visit_list
(
`user_id` BIGINT NOT NULL COMMENT '用户 ID',
`dt` DATE NOT NULL COMMENT '业务日期',
`city` VARCHAR(32) NOT NULL COMMENT '城市',
`visit_count` BIGINT SUM DEFAULT '0' COMMENT '访问次数'
)
ENGINE = OLAP
AGGREGATE KEY(`user_id`, `dt`, `city`)
PARTITION BY LIST(`city`)
(
PARTITION `p_north` VALUES IN ('Beijing', 'Tianjin'),
PARTITION `p_east` VALUES IN ('Shanghai', 'Hangzhou'),
PARTITION `p_south` VALUES IN ('Guangzhou', 'Shenzhen')
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 4
PROPERTIES
(
"replication_num" = "1"
);
只有 city 命中某个分区枚举值时,数据才能写入。例如 Beijing 会进入 p_north,而没有定义的 Chengdu 无法命中以上任何分区,写入会失败。
1.1 增加一个西部地区分区
sql
ALTER TABLE demo.user_visit_list
ADD PARTITION `p_west` VALUES IN ('Chengdu', 'Chongqing')
DISTRIBUTED BY HASH(`user_id`) BUCKETS 4;
1.2 删除一个分区
sql
ALTER TABLE demo.user_visit_list
DROP PARTITION `p_east`;
删除分区会连同该分区内的全部数据一起移除,因此在大批量历史数据清理场景中,删分区通常比逐行 DELETE 更高效。
2. 分桶列与桶数怎么选
2.1 分桶列
分桶列通常选择:
- 经常出现在等值查询条件中的列,例如
WHERE user_id = 1001; - 基数较高、取值较均匀的列;
- 不容易造成大量数据集中到少数桶中的列。
本例选择:
sql
DISTRIBUTED BY HASH(`user_id`) BUCKETS 4
相同 user_id 会通过稳定的 Hash 规则落入对应桶中。分区表的 Hash 分桶规则会在每个分区内部分别应用,因此本例每个分区都有 4 个 Tablet。
2.2 桶数
本地练习可从 1~4 个桶开始:
- 数据很少、只验证语法:1 个桶即可;
- 想观察 Tablet 和分桶:可使用 4 个桶;
- 不要因为生产环境桶数较多,就在单机小数据测试中照搬几十或几百个桶。
如果 Range 表有 3 个分区、每个分区 4 个桶、副本数为 1,则可近似理解为:
text
3 个 Partition × 4 个 Tablet × 1 个 Replica = 12 个 Tablet 副本
这些副本全部存放在唯一的 BE 上,因此增加桶数不会带来跨 BE 的并行能力或高可用能力。
3. 多列分区
Doris 支持使用多列进行 Range 或 List 分区。比较时按列顺序进行,理解和维护成本更高,入门阶段建议优先使用单列分区。
多列 List 示例:
sql
PARTITION BY LIST(`tenant_id`, `city`)
(
PARTITION `p1` VALUES IN (('1', 'Beijing'), ('1', 'Shanghai')),
PARTITION `p2` VALUES IN (('2', 'Beijing'), ('2', 'Shanghai'))
)
4. 什么时候使用"分区 + 分桶"
适合使用两层划分的常见场景:
- 按时间管理数据:按天或按月建分区,查询时利用分区裁剪。
- 定期清理历史数据:直接删除过期分区,比逐行删除更适合大批量历史数据清理。
- 不同周期数据量差异较大:可为不同分区规划不同桶数。
- 需要控制单个 Tablet 的数据量:在分区内部继续分桶,避免一个逻辑分片过大。
如果表非常小、没有历史分区管理需求,可以不显式分区,只保留 Hash 分桶。
5. 查看与验证
查看 BE 节点:
sql
SHOW BACKENDS;
查看建表语句:
sql
SHOW CREATE TABLE demo.user_visit_range;
查看分区:
sql
SHOW PARTITIONS FROM demo.user_visit_range;
查看 Tablet 分布:
sql
SHOW TABLETS FROM demo.user_visit_range;
验证分区裁剪:
sql
EXPLAIN
SELECT SUM(visit_count)
FROM demo.user_visit_range
WHERE dt >= '2026-02-01'
AND dt < '2026-03-01';
在 EXPLAIN 结果中,如果 partitions 只列出 2 月对应的分区,说明分区裁剪已生效,查询不会扫描无关分区。