【StarRocks系列】join查询优化
目录
Join 类型 和 Join 策略
1. Join 类型(Join Type)
2. Join 策略(Join Strategy)
分布式 Join 策略 (核心)
1. Colocate Join (本地 Join - 最优):
2. Bucket Shuffle Join:
3. Broadcast Join (复制广播):
4. Shuffle Join (重分区):
5. Replicated Join (复制表):
6. 运行时优化
a. Runtime Filter (运行时过滤器 - 核心加速)
b. Join 算法优化
c. Cost-Based Optimizer (CBO - 基于成本的优化器)
d. 谓词下推 (Predicate Pushdown)
显式启用join策略
总结与最佳实践建议:
优化实践
Join 类型 和 Join 策略
Join 类型(Join Type) 和 Join 策略(Join Strategy) 是两个不同层面的概念,它们的可控制性也不同:
1. Join 类型(Join Type)
- 是什么? 指 SQL 标准定义的
INNER JOIN
,LEFT JOIN
,RIGHT JOIN
,FULL OUTER JOIN
,SEMI JOIN
,ANTI JOIN
等语义类型。 - 能否显式指定? ✅ 可以且必须显式指定!
-
- 您在编写 SQL 查询时,必须在
FROM
/JOIN
子句中明确写出您需要的 Join 类型(如SELECT ... FROM fact_table INNER JOIN dim_table ON ...
)。 - 这是 SQL 语法的一部分,StarRocks 会严格按照您指定的语义执行。
- 您在编写 SQL 查询时,必须在
- 优化器的影响: CBO 优化器会根据您指定的 Join 类型、表大小、过滤条件等选择最高效的执行策略(如 Colocate/Broadcast/Shuffle),但不会改变您指定的 Join 语义。
2. Join 策略(Join Strategy)
- 是什么? 指在分布式环境下执行 Join 操作时采用的物理实现方式,即您之前问题中提到的:
-
Colocate Join
Bucket Shuffle Join
Broadcast Join
Shuffle Join
Replicated Join
(通过表属性实现)
- 能否显式指定? ⚠️ 通常不能(或不建议)直接在 SQL 中强制指定!
-
- StarRocks 的 Cost-Based Optimizer (CBO) 是自动选择它认为最优的 Join 策略的。
- CBO 的决策基于:
-
-
- 表的分区分桶定义(是否满足 Colocate 条件)。
- 表的统计信息(大小、基数)。
- Join 条件。
- 相关系统参数(如
broadcast_row_limit
)。
-
-
- 设计目标: 让优化器基于数据和统计信息自动选择最高效的策略,用户无需手动干预复杂的分布式执行细节。
分布式 Join 策略 (核心)
1. Colocate Join (本地 Join - 最优):
-
-
- 原理: 参与 Join 的多张表使用相同分区方式和分桶方式(Distributed By),且分桶数相同。
- 优势: 相同分桶键的数据必然落在同一个 BE 节点上。Join 计算完全在本地节点内完成,无需跨节点数据 Shuffle,网络开销为零。
- 适用场景: 星型/雪花模型中的事实表与维度表关联(维度表通常较小,可复制或采用 Colocate 分区),或大表与大表关联(前提是分区策略匹配且数据分布均匀)。
-
2. Bucket Shuffle Join:
-
-
- 原理: 当左表(通常是驱动表/事实表)分桶,且 Join 的
ON
子句中包含左表的分桶列时启用。 - 优势: 右表(通常是维度表)的数据会根据左表的分桶规则进行 Shuffle,分发到左表数据所在的 BE 节点。Join 计算在节点本地进行(左表数据不动)。相比 Broadcast 和 Shuffle,网络传输量显著减少。
- 适用场景: 事实表(左表)与维度表(右表)关联,且 Join Key 包含事实表的分桶列。比 Broadcast 更能处理较大的右表。
- 原理: 当左表(通常是驱动表/事实表)分桶,且 Join 的
-
3. Broadcast Join (复制广播):
-
-
- 原理: 将较小的右表(或查询结果)完整复制到所有包含左表数据的 BE 节点上。
- 优势: 每个 BE 节点持有完整的右表数据,可以在本地与左表的分片进行 Join,无需跨节点传输左表数据。
- 适用场景: 右表非常小(通常建议 < 100MB)时非常高效。如果右表过大,网络传输和内存开销会很大,甚至 OOM。
-
4. Shuffle Join (重分区):
-
-
- 原理: 根据 Join Key 的 Hash 值,将左表和右表的数据都进行 Shuffle 重分布,确保相同 Join Key 的数据落到同一个 BE 节点上,然后在该节点进行本地 Join。
- 优势: 适用于两张大表关联且无法使用 Colocate 或 Bucket Shuffle 的场景。
- 劣势: 网络传输开销最大,因为两张表的数据都需要跨节点传输。是其他策略不适用时的保底方案。
-
5. Replicated Join (复制表):
-
-
- 原理: 将维度表定义为
replicated
属性,StarRocks 会自动在集群所有 BE 节点上存储该表的完整副本。 - 优势: 任何 Join 涉及该复制表时,都可以直接在本地 BE 节点上进行,完全避免网络传输,效果类似于 Broadcast Join 但无需运行时广播。
- 适用场景: 小维度表(能容忍全集群存储多份副本)。需要建表时指定
PROPERTIES ("replicated_storage" = "true")
。
- 原理: 将维度表定义为
-
6. 运行时优化
a. Runtime Filter (运行时过滤器 - 核心加速)
-
- 原理: 在 Join 计算时(尤其是 Hash Join),StarRocks 会动态地从右表(Build Side)提取 Join Key 的最小/最大值(Min/Max Filter)或构建一个 Bloom Filter。
- 优势: 将这个 Filter 下推到左表(Probe Side)的扫描算子。左表在读取数据时,可以利用这个 Filter 提前过滤掉大量不可能匹配 Join Key 的行,显著减少需要参与后续 Join 计算的数据量。
- 类型: 支持
IN
,MIN_MAX
,BLOOM_FILTER
。通常BLOOM_FILTER
效果最佳。 - 适用场景: 对大表作为 Probe Side 的 Join 性能提升巨大,尤其是当 Join Key 具有高选择性时。通过
set global runtime_join_filter_push_down_limit = X;
控制适用右表大小上限。
b. Join 算法优化
-
- 向量化 Hash Join: StarRocks 的向量化执行引擎对 Hash Join 算法进行了深度优化。它利用 SIMD 指令集,一次处理一批数据(向量),极大地提高了 CPU 利用率和缓存命中率,加速 Join 计算过程。
- 多表 Join 顺序优化: StarRocks 的 CBO 优化器会根据表大小、过滤条件和统计信息,智能选择最优的 Join 顺序,尽量先过滤掉更多数据再进行 Join,减少中间结果集大小。
c. Cost-Based Optimizer (CBO - 基于成本的优化器)
-
- 原理: StarRocks 收集并维护表的统计信息(行数、列 NDV、NULL 值数、Min/Max 值、数据分布直方图等)。
- 优势: CBO 利用这些统计信息,估算不同 Join 策略(Colocate/Bucket Shuffle/Broadcast/Shuffle)和不同 Join 顺序的成本,并选择它认为执行成本最低的计划。
- 关键: 需要定期执行
ANALYZE TABLE
命令更新统计信息,CBO 才能做出更准确的判断。
d. 谓词下推 (Predicate Pushdown)
-
- 原理: 优化器会尽可能将 Join 条件或 WHERE 条件中的过滤条件下推到数据扫描的最早阶段。
- 优势: 在扫描磁盘或从内存读取数据时,就应用这些过滤条件,尽早过滤掉不相关的数据,减少后续算子(特别是 Join)需要处理的数据量。
显式启用join策略
分析查询 | StarRocks
总结与最佳实践建议:
- 查看执行计划: 使用
EXPLAIN
/EXPLAIN ANALYZE
查看执行计划,确认优化器选择了期望的策略(如colocate: true
,runtime filters
信息)。根据执行情况调整表结构、查询写法或优化器参数。
分析查询 | StarRocks
- 首选 Colocate Join: 表设计阶段,对于需要高频 Join 且数据量大的表,优先考虑使用相同的分区分桶策略。这是性能最高的 Join 方式。
- 善用 Bucket Shuffle Join: 当无法 Colocate 时,确保事实表(左表)按 Join Key 分桶,并让 Join Key 包含分桶列。
- 控制 Broadcast Join 使用范围: 仅对小表使用 Broadcast Join。通过
SET broadcast_row_limit = X;
控制优化器选择 Broadcast 的阈值。 - 务必启用 Runtime Filter: 这是加速大表 Join 的利器。通常保持默认开启即可,效果显著。
- 维护准确的统计信息: 定期
ANALYZE TABLE
是 CBO 发挥效力的基础。 - 合理选择 Join 类型: 根据业务语义和数据特点选择
INNER JOIN
,LEFT OUTER JOIN
,RIGHT OUTER JOIN
,FULL OUTER JOIN
,SEMI JOIN
,ANTI JOIN
等。优化器对不同类型可能有不同优化策略。 - 避免笛卡尔积: 确保 Join 条件有效,除非业务确实需要笛卡尔积。
通过综合运用这些优化技术,StarRocks 能够高效地处理各种复杂和大规模的 Join 查询,满足高性能分析的需求。理解这些原理对于设计和优化高效的 StarRocks 查询至关重要。
优化实践
StarRocks 技术内幕 | Join 查询优化
StarRocks 技术内幕 | Join 查询优化_starrocks join-CSDN博客
StarRocks-Profile分析及优化指南
StarRocks-Profile分析及优化指南 - 经验教程 - StarRocks中文社区论坛