StarRocks 中的 Operator(操作符) 是执行引擎中的基本计算单元,它们组成了查询的执行计划。每个 Operator 负责完成一个特定的、相对单一的数据处理任务。
由于 StarRocks 的架构在持续演进,其 Operator 体系也经历了从传统的基于行的模型到向量化批处理模型的转变。目前,主要围绕向量化执行引擎和 Pipeline 引擎来组织。
以下是 StarRocks 中主要 Operator 的分类和详解:
1. 数据源 Operator(Scan)
这类 Operator 负责从数据源读取数据,是执行计划的起点。
-
OlapScanOperator :最核心、最常用的扫描 Operator 。负责从 StarRocks 本地的存储引擎(存储格式为
star_index
+data
文件)中扫描数据。它会利用分区裁剪、前缀索引、ZoneMap 索引、Bitmap 索引、Bloom Filter 等技术高效地读取列式数据块。 -
FileScanOperator:用于查询外部数据源,如 HDFS、S3 上的 Parquet、ORC、CSV 等格式的文件。允许直接对外部数据进行分析(ELT)。
-
ESScanOperator:专门用于扫描 Elasticsearch 外部表,将查询下推到 ES 集群执行。
-
JDBCScanOperator:用于查询 JDBC 外部表(如 MySQL、PostgreSQL 等数据库)。
2. 计算与转换 Operator(单节点计算)
这类 Operator 在单个节点上对数据流进行变换和处理,通常不涉及网络传输。
-
ProjectOperator :投影操作 。用于选择查询中指定的列,或计算新的列(例如
SELECT a, b+1 AS c FROM table
中的b+1
)。 -
FilterOperator / PredicateOperator :过滤操作。根据 WHERE 子句中的条件对数据进行筛选。它利用向量化执行,对一整批数据快速应用过滤条件。
-
AggregateOperator :聚合操作 。执行
COUNT
,SUM
,AVG
,MAX
,MIN
以及GROUP BY
等聚合计算。在 MPP 中,它通常分为两个阶段:-
本地聚合:在数据所在的 BE 上先进行预聚合,减少数据量。
-
全局聚合:对本地聚合的结果进行最终汇总。
-
-
SortOperator :排序操作 。用于
ORDER BY
子句。它是一个阻塞 Operator,因为它需要接收到所有数据后才能完成排序。 -
TopNOperator :TopN 排序/限制操作 。用于
ORDER BY ... LIMIT N
。它比全量排序更高效,因为不需要对所有数据进行完全排序,只需维护一个大小为 N 的堆。 -
LimitOperator :限制操作 。用于
LIMIT N
子句,简单截断数据流,只返回前 N 行。 -
HashJoinOperator :哈希连接操作 。用于
JOIN
操作。它会为连接的一端(通常是右表/构建端)在内存中构建一个哈希表,然后用另一端(左表/探测端)的数据去这个哈希表中查找匹配的行。这是最常用的 Join 方式。 -
MergeJoinOperator :归并连接操作。当左右两边的输入数据都已经按照连接键排好序时,可以使用这种更高效的连接方式。
-
WindowOperator :窗口函数操作 。用于计算窗口函数,如
ROW_NUMBER()
,RANK()
,SUM() OVER (PARTITION BY ...)
等。
3. 数据交换 Operator(网络与数据重分布)
这类 Operator 是 MPP 架构的核心,负责在不同 BE 节点之间移动和重新分布数据,以实现并行计算。
-
ExchangeOperator:这是一个逻辑上的统称,在实际执行计划中通常表现为:
-
ExchangeSourceOperator :数据接收端。从一个或多个上游 BE 节点接收通过网络发送过来的数据。
-
ExchangeSinkOperator :数据发送端。将本节点的数据按照某种分区规则(如 Hash、Broadcast、随机)发送给下游的 BE 节点。
-
数据交换类型(Shuffle):
-
HASH_PARTITION :按某个键的哈希值将数据分布到不同节点,用于
GROUP BY
非分区键或JOIN
。 -
BROADCAST:将小表的数据广播到所有包含大表数据的节点上,用于 Broadcast Join。
-
SINGLETON:将数据汇集到单个节点(例如需要全局排序或最终聚合的节点)。
-
RANDOM:随机分布数据,用于平衡负载。
-
-
4. 其他特殊 Operator
-
AnalyticOperator:与分析函数相关(类似于 WindowOperator,但具体实现可能有所不同)。
-
CrossJoinOperator :笛卡尔积连接 ,用于没有连接条件的
JOIN
,使用较少。 -
RepeatOperator :用于配合
GROUPING SETS
、CUBE
或ROLLUP
等高级分组操作,生成多维度分组的结果。
如何查看执行计划中的 Operator?
您可以通过 EXPLAIN
命令来查看一个查询的执行计划,从而观察这些 Operator 是如何组装的。
示例 1:简单的扫描和聚合
EXPLAIN SELECT customer_id, SUM(amount)
FROM sales
WHERE dt = '2023-10-01'
GROUP BY customer_id;
在这个计划中,您可能会看到:
OlapScanNode
-> HashAggNode
(本地聚合) -> EXCHANGE
(网络Shuffle) -> HashAggNode
(全局聚合)
示例 2:带 Join 的查询
EXPLAIN SELECT s.order_id, c.customer_name
FROM sales s JOIN customers c ON s.customer_id = c.customer_id;
计划中可能包含:
OlapScanNode
(sales) -> HashJoinNode
(构建端/探测端) -> EXCHANGE
(Broadcast customers 表) -> OlapScanNode
(customers)
注意 :在 EXPLAIN
的输出中,你可能会看到 XXXNode
和 XXXOperator
的术语。可以简单理解为:
-
Node: 是逻辑执行计划中的概念,由 FE 生成。
-
Operator: 是物理执行计划中的概念,是 Node 在 BE 上的具体执行实体。
总结
StarRocks 的 Operator 体系是其高性能查询引擎的基石。它们通过 向量化处理 (一次处理一批数据)和 Pipeline 执行 (异步流水线,避免阻塞)实现了极高的执行效率。理解这些 Operator 的功能,对于进行 SQL 调优(例如,通过执行计划判断是否出现了不该有的 CrossJoin
,或 HashJoin
的构建端是否过大)至关重要。