跳到主要内容
版本:3.4

分区

在 StarRocks 中,实现快速分析的第一步是设计一个与查询模式相匹配的表布局。本指南将实践经验提炼为清晰的分区规则,帮助您:

  • 通过积极的分区裁剪减少扫描数据量
  • 使用仅元数据操作管理生命周期任务(TTL、GDPR 删除、分层存储)
  • 随着租户数量、数据量或保留窗口的增长平稳扩展
  • 控制写放大——新数据进入“热”分区;数据Compaction发生在历史分区中

在建模新表或重构旧表时,请牢记这些建议——每个部分都提供目标导向的标准、设计启发和操作防护措施,以避免将来进行代价高昂的重新分区。

分区与分桶——不同的任务

在设计高性能的 StarRocks 表时,理解分区和分桶之间的区别是至关重要的。虽然两者都有助于管理大型数据集,但它们的用途不同:

  • 分区允许 StarRocks 在查询时通过分区裁剪跳过整个分区,并启用仅元数据的生命周期操作,如删除旧数据或特定租户的数据。
  • 分桶则有助于将数据分布在多个 tablet 上,以并行化查询执行和均衡负载,特别是在与哈希函数结合使用时。
方面分区分桶(哈希/随机)
主要目标粗粒度的数据裁剪和生命周期控制(TTL、归档)。细粒度的并行度和每个分区内的数据局部性。
计划器可见性分区是 catalog 对象;FE 可以通过谓词跳过它们。仅等值谓词支持分桶裁剪
生命周期操作DROP PARTITION 是仅元数据操作——理想用于 GDPR 删除、每月滚动。桶不能被删除;它们仅通过 ALTER TABLE … MODIFY DISTRIBUTED BY 更改。
典型数量每个表 10^2–10^4(天、周、租户)。每个分区 10–120;StarRocks BUCKETS xxx 调整此值。
倾斜处理合并或拆分分区;考虑复合/混合方案。提高桶数量,哈希复合键,隔离“大租户”,或使用随机分桶
警示信号> 100k 分区可能会给 FE 带来显著的内存开销> 200k tablet/BE;单个 tablet 超过 10 GB 可能遇到Compaction问题。

什么时候应该分区?

表模型分区?典型键
事实/事件流date_trunc('day', event_time)
大型维度(数十亿行)有时时间或业务键变更日期
小型维度/查找依赖哈希分布

选择分区键

  1. 时间优先默认——如果 80% 的查询包含时间过滤器,则以 date_trunc('day', dt) 开始。
  2. 租户隔离——在需要按租户进行数据管理时,将 tenant_id 纳入分区键。
  3. 保留对齐——将计划清理的列纳入分区键。
  4. 复合键PARTITION BY tenant_id, date_trunc('day', dt) 可以实现完美裁剪,但会创建 #tenants × #days 个分区。保持总数低于 ≈ 100k,否则 FE 内存和 BE Compaction会受影响。

选择粒度

PARTITION BY date_trunc('day', dt) 的粒度应根据使用场景进行调整。可选择“小时”“天”“月”等粒度。参见 date_trunc

粒度适用场景优点缺点
每日(默认)大多数 BI 和报告少量分区(365/年);简单的 TTL对“最近 3 小时”查询不够精确
每小时每天产生的 tablet 数 > 2×;适用于 IoT 突发热点隔离;24 分区/天每年 8 700 分区
每周/每月历史归档元数据小;合并容易粗粒度裁剪
  • 经验法则:保持每个分区 ≤ 100 GB,且每个分区 ≤ 20k tablet(跨副本)。
  • 混合粒度:从 3.4 版本开始,StarRocks 支持通过将历史分区合并为更粗粒度来实现混合粒度。

示例方案

点击流事实(单租户)

CREATE TABLE click_stream (
user_id BIGINT,
event_time DATETIME,
url STRING,
...
)
DUPLICATE KEY(user_id, event_time)
PARTITION BY date_trunc('day', event_time)
DISTRIBUTED BY HASH(user_id) BUCKETS xxx;

SaaS 指标(多租户,模式 A)

推荐用于大多数 SaaS 工作负载。按时间裁剪,保持租户数据共置。

CREATE TABLE metrics (
tenant_id INT,
dt DATETIME,
metric_name STRING,
v DOUBLE
)
PRIMARY KEY(tenant_id, dt, metric_name)
PARTITION BY date_trunc('DAY', dt)
DISTRIBUTED BY HASH(tenant_id) BUCKETS xxx;

大租户复合(模式 B)

当需要特定租户的 DML/DDL 或存在大规模租户时,需注意潜在的分区爆炸。

CREATE TABLE activity (
tenant_id INT,
dt DATETIME,
id BIGINT,
....
)
DUPLICATE KEY(dt, id)
PARTITION BY tenant_id, date_trunc('MONTH', dt)
DISTRIBUTED BY HASH(id) BUCKETS xxx;
Rocky the happy otterStarRocks Assistant

AI generated answers are based on docs and other sources. Please test answers in non-production environments.