StarRocks查询加速

StarRocks 之所以快,除了向量化执行引擎外,还依赖丰富的数据组织和索引技术。

核心技术

1. 物化视图 (Materialized View)

  • 文件 : 01_materialized_view.sql
  • 原理: 空间换时间。预先计算好聚合结果(如 SUM, COUNT),查询时自动路由。
  • 类型:
  • 单表同步 MV (示例中演示): 实时更新,强一致。
  • 多表异步 MV (2.4+): 支持复杂 Join,定期刷新。

2. 索引 (Indexing)

  • 文件 : 02_indexes.sql
  • Bitmap Index : 适合性别、省份等枚举值少的列。加速 WHERE col = 'A'
  • Bloom Filter : 适合 ID、UUID 等取值多的列。加速 WHERE id = 123,快速跳过不包含该 ID 的数据块。
  • Prefix Index (前缀索引): 默认建立在排序键 (Sort Key) 的前 36 字节。建表时合理设置 Key 顺序至关重要!

3. 分区与分桶 (Partition & Bucket)

  • 文件 : 03_partitioning.sql
  • Partition: 宏观切割,通常按时间。查询带时间范围时直接裁剪掉无关分区。
  • Bucket: 微观切割,按 Hash。利用集群并行计算能力。

最佳实践

  • 排序键 (Sort Key): 将查询频率最高的过滤列放在 Key 的最前面(利用前缀索引)。
  • 分区 : 大表(亿级以上)务必按时间分区,并开启动态分区 (dynamic_partition)。
sql 复制代码
-- Phase 4: 查询加速
-- 01_materialized_view.sql
-- 同步物化视图 (Synchronous Materialized View)

USE learn_starrocks;

-- 假设我们有一个销售明细表
CREATE TABLE IF NOT EXISTS sales_records (
    record_id INT,
    seller_id INT,
    store_id INT,
    sale_date DATE,
    sale_amt DECIMAL(10, 2)
)
ENGINE=OLAP
DUPLICATE KEY(record_id)
DISTRIBUTED BY HASH(record_id) BUCKETS 3
PROPERTIES ("replication_num" = "1");

-- 场景:我们经常需要查询每个店铺的销售总额
-- SELECT store_id, SUM(sale_amt) FROM sales_records GROUP BY store_id;
-- 这种查询在数据量大时,每次都要扫描全表并聚合,很慢。

-- 创建物化视图:预先计算好聚合结果
-- 注意:StarRocks 会自动维护 MV 的数据一致性(源表插入数据,MV 自动更新)
CREATE MATERIALIZED VIEW mv_store_sales 
AS
SELECT 
    store_id, 
    SUM(sale_amt) AS total_amt 
FROM sales_records 
GROUP BY store_id;

-- 验证 MV 是否生效
-- 插入数据
INSERT INTO sales_records VALUES 
(1, 101, 1, '2023-01-01', 100.00),
(2, 102, 1, '2023-01-01', 200.00),
(3, 103, 2, '2023-01-01', 50.00);

-- 执行查询
-- StarRocks 优化器会自动路由到 mv_store_sales 视图,而不需要显式查询视图
EXPLAIN SELECT store_id, SUM(sale_amt) FROM sales_records GROUP BY store_id;
-- 在 EXPLAIN 结果中,如果看到 `Rollup: mv_store_sales`,说明命中 MV
sql 复制代码
-- Phase 4: 查询加速
-- 02_indexes.sql
-- 索引技术:Bitmap Index 和 Bloom Filter Index

USE learn_starrocks;

CREATE TABLE IF NOT EXISTS user_events (
    event_id BIGINT,
    user_id INT,
    event_type VARCHAR(20), -- 基数小 (Login, Logout, Click) -> 适合 Bitmap
    device_uuid VARCHAR(100), -- 基数大 -> 适合 Bloom Filter
    event_time DATETIME
)
ENGINE=OLAP
DUPLICATE KEY(event_id)
DISTRIBUTED BY HASH(event_id) BUCKETS 3
PROPERTIES (
    "replication_num" = "1",
    
    -- 1. Bloom Filter 索引
    -- 适用于高基数列的等值查询 (user_id = 123)
    -- 注意:Bloom Filter 只能判断"可能存在"或"一定不存在",用于快速过滤文件块
    "bloom_filter_columns" = "device_uuid"
);

-- 2. Bitmap 索引
-- 适用于低基数列 (枚举值少) 的查询,支持等值、IN、OR
-- 可以在建表后添加,也可以建表时指定
CREATE INDEX idx_event_type ON user_events(event_type) USING BITMAP COMMENT "Bitmap index for event type";

-- 验证
SHOW INDEX FROM user_events;
sql 复制代码
-- Phase 4: 查询加速
-- 03_partitioning.sql
-- 分区与分桶 (Partitioning & Bucketing)

USE learn_starrocks;

-- 分区 (Partition): 通常按时间划分 (按天/按月)。
-- 分桶 (Bucket): 在分区内进一步打散数据,通常按 ID 哈希。
-- 目的:查询时通过分区裁剪 (Partition Pruning) 减少扫描的数据量。

CREATE TABLE IF NOT EXISTS bill_detail (
    bill_id BIGINT,
    bill_date DATE,
    amount DECIMAL(10, 2)
)
ENGINE=OLAP
DUPLICATE KEY(bill_id, bill_date)
PARTITION BY RANGE(bill_date) (
    -- 手动创建分区
    PARTITION p202301 VALUES LESS THAN ("2023-02-01"),
    PARTITION p202302 VALUES LESS THAN ("2023-03-01"),
    PARTITION p202303 VALUES LESS THAN ("2023-04-01")
)
DISTRIBUTED BY HASH(bill_id) BUCKETS 3
PROPERTIES (
    "replication_num" = "1",
    -- 动态分区配置 (强烈推荐):自动管理分区创建和删除
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "MONTH",
    "dynamic_partition.start" = "-2", -- 保留过去2个月
    "dynamic_partition.end" = "2",    -- 预创建未来2个月
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.buckets" = "3"
);

-- 查询优化演示
-- 查询 2023-01 的数据时,只会扫描 p202301 分区,忽略其他分区
SELECT * FROM bill_detail WHERE bill_date >= '2023-01-01' AND bill_date < '2023-01-15';

-- 查看分区情况
SHOW PARTITIONS FROM bill_detail;
相关推荐
丷丩6 分钟前
Postgresql基础实践教程(十一)各种Join
数据库·postgresql·join
星夜夏空9921 分钟前
FreeRTOS学习(4)——内存映射
数据库·学习·mongodb
TheRouter1 小时前
AI Agent 记忆体系建设实战:短期、长期与工作记忆的工程实现
数据库·人工智能·oracle
Omics Pro1 小时前
首个!外源天然产物综合性代谢图谱
数据库·人工智能·算法·机器学习·r语言
JAVA面经实录9172 小时前
Hibernate面试题库
数据库·oracle·hibernate
迷枫7123 小时前
DM8 目录结构与常用排查入口梳理
服务器·数据库
Mr.Daozhi4 小时前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具
小程故事多_804 小时前
Claude Code自定义workflow skills用法
数据库·人工智能·智能体
大鹏说大话4 小时前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
夏贰四5 小时前
数据建模工具如何筑牢数据根基?数据建模工具怎样落实标准体系?
数据库·数学建模·数据建模工具