CodeWalk

StarRocks聚合模型与Bitmap精确去重

作者:屠龙少年 · 2026-05-30 12:55

StarRocks的聚合模型(Aggregate Model)支持哪些聚合函数类型?如何利用聚合模型实现高效的数据预聚合?请说明如何使用Bitmap实现精确去重(Count Distinct),以及聚合模型中物化视图透明改写的原理。

回答

屠龙少年

1. 聚合模型支持的聚合类型

CREATE TABLE site_visit (
  site_id INT,
  date DATE,
  pv BIGINT SUM,
  uv BITMAP_UNION,
  max_temp DOUBLE MAX,
  first_visit DATETIME REPLACE
)
AGGREGATE KEY (site_id, date)
DISTRIBUTED BY HASH(site_id);

支持函数:

  • SUM、MAX、MIN、REPLACE
  • HLL_UNION(近似去重)
  • BITMAP_UNION(精确去重)
  • PERCENTILE_UNION

2. 数据预聚合机制

导入时:相同Key的数据自动合并
查询时:读取预聚合结果,无需扫描明细
效果:亿级数据预聚合后降低到万级

3. Bitmap精确去重

-- 建表
CREATE TABLE user_uv (
  dt DATE,
  user_id BITMAP BITMAP_UNION
) AGGREGATE KEY (dt);

-- 导入时使用to_bitmap函数
INSERT INTO user_uv VALUES ('2024-01-01', to_bitmap(1001));

-- 查询精确UV
SELECT dt, bitmap_count(uv) FROM user_uv;

-- 跨天去重
SELECT bitmap_count(bitmap_union(uv)) FROM user_uv;  

Bitmap优势

  • 精确去重,不会Like HyperLogLog(误差1-5%)
  • 内存占用可控(1亿用户≈120MB)

4. 物化视图透明改写

-- 创建物化视图
CREATE MATERIALIZED VIEW mv_pv_by_hour AS
SELECT site_id, date_trunc('hour', ts) as hour, COUNT(*)
FROM site_visit
GROUP BY site_id, hour;

-- 查询自动改写
-- 原始SQL
SELECT site_id, DATE(ts), COUNT(*) FROM site_visit GROUP BY site_id, DATE(ts);
-- 自动改为查mv_pv_by_hour(无需修改SQL)

透明改写条件

  • 查询的聚合函数必须匹配
  • 查询的维度是MV维度的子集或超集
  • 查询的过滤条件包含MV的过滤条件

5. 适用场景

  • 高并发报表查询
  • 实时OLAP分析
  • ClickHouse替代(对精确去重有要求)