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;
相关推荐
静听山水3 小时前
StarRocks高级特性
数据库
范纹杉想快点毕业3 小时前
从单片机基础到程序框架:全方位技术深度解析
数据库·mongodb
晚风_END3 小时前
Linux|操作系统|elasticdump的二进制方式部署
运维·服务器·开发语言·数据库·jenkins·数据库开发·数据库架构
devmoon3 小时前
Polkadot SDK 自定义 Pallet Benchmark 指南:生成并接入 Weight
开发语言·网络·数据库·web3·区块链·波卡
数据知道3 小时前
PostgreSQL 故障排查:紧急排查与 SQL 熔断处理(CPU 占用 100% 等情况)
数据库·sql·postgresql
静听山水3 小时前
Redis的Pipeline (管道)
数据库·redis·php
数据知道3 小时前
PostgreSQL 性能优化: I/O 瓶颈分析,以及如何提高数据库的 I/O 性能?
数据库·postgresql·性能优化
繁华落尽,寻一世真情3 小时前
【基于 AI 的智能小说创作助手】MuMuAINovel-sqlite 基于 AI 的智能小说创作助手
数据库·人工智能·sqlite
TOPGO智能3 小时前
在腾讯CloudStudio上成功部署Moltbot接入飞书
数据库