跳到主要内容
版本:Latest-3.5

分区

在 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 AUTO 调整此值。
倾斜处理合并或拆分分区;考虑复合/混合方案。提高桶数量,哈希复合键,隔离“大户”,或使用随机分桶
警示信号>100 k 分区可能会对 FE 引入显著的内存占用>200 k tablet 每个 BE;超过 10 GB 的 tablet 可能遇到 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 个分区。保持总数低于 ≈ 100 k,否则 FE 内存和 BE compaction 会受到影响。

选择粒度

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

粒度适用场景优点缺点
每日(默认)大多数 BI 和报告少量分区(365/年);简单的 TTL对“最近 3 小时”查询不够精确
每小时每天 > 2 × tablet;物联网突发热点隔离;24 分区/天每年 8 700 分区
每周/每月历史归档元数据小;合并容易粗粒度裁剪
  • 经验法则:保持每个分区 ≤ 100 GB 和每个分区 ≤ 20 k 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 AUTO;

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 AUTO;

大租户复合(模式 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 AUTO;