---
title: "GROUP BY - OceanBase 数据库 V4.3.5 | OceanBase 文档中心"
description: GROUP BY GROUP BY 算子主要用于在 SQL 中进行分组聚合计算操作。 GROUP BY 算子类型 OceanBase 数据库用于对数据进行分组的算法有 HASH 算法和 MERGE 算法，因此根据算法可以将 GROUP BY 算子分为两种： HASH GROUP BY 和 MERGE GROUP BY…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.3.5 LTS

# GROUP BY

更新时间：2026-07-19 16:40:56

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.3.5/zh-CN/700.reference/1000.performance-tuning-guide/500.sql-optimization/200.sql-execution-plan/400.execution-plan-operator/500.group-by.md)  

`GROUP BY` 算子主要用于在 SQL 中进行分组聚合计算操作。

## GROUP BY 算子类型

OceanBase 数据库用于对数据进行分组的算法有 `HASH` 算法和 `MERGE` 算法，因此根据算法可以将 `GROUP BY` 算子分为两种：`HASH GROUP BY` 和 `MERGE GROUP BY`。执行计划生成时根据 SQL 优化器对于两种算子的代价评估，来选择使用哪种 `GROUP BY` 算子。

对于普通的聚合函数（`SUM`/`MAX`/`MIN`/`AVG`/`COUNT`/`STDDEV`）也是通过分配 `GROUP BY` 算子来完成，而对于只有聚合函数而不含有 `GROUP BY` 的 SQL，分配的是 `SCALAR GROUP BY` 算子，因此 `GROUP BY` 算子又可以分为三种：`SCALAR GROUP BY`、`HASH GROUP BY` 和 `MERGE GROUP BY`。

| 算子类型 | 特性说明 | 核心原理 | 适用场景 |
| --- | --- | --- | --- |
| SCALAR GROUP BY | 用于处理不含 `GROUP BY` 子句，但包含聚合函数（如 `SUM`, `COUNT`）的查询，对全表数据进行单一聚合。 | 对整张表的数据进行一次聚合计算，无需分组操作。 | 全局聚合统计，例如计算某列的总和、平均值、总行数等。 |
| HASH GROUP BY | 使用哈希表进行分组聚合，通常无需数据预先排序。 | 为每个不同的分组键计算一个哈希值，将相同哈希值的行放入同一桶中进行聚合计算。 | 分组键重复值较多或数据分布均匀时效率高，是常用的分组算法。 |
| MERGE GROUP BY | 使用排序合并算法进行分组聚合，要求输入数据已按分组键排序。 | 先确保数据按分组键有序（可能需额外 `SORT` 算子），然后顺序扫描已排序的数据流，合并相同键值的行进行聚合。 | 当数据已有序（如通过索引扫描获得），或需要保持输出有序时可能被优化器选用。 |

## SCALAR GROUP BY

`SCALAR GROUP BY` 算子用于执行不含 `GROUP BY` 子句的标量聚合查询，即对整个结果集计算一个单一的聚合值。

### SCALAR GROUP BY 示例

1. 创建表 `tbl1`。

   ```shell
   obclient> CREATE TABLE tbl1 (col1 INT, col2 INT);

   ```
 2. Q1：对表 `tbl1` 中 `col1` 列进行求和，同时查看该查询的执行计划。

   ```shell
   obclient> EXPLAIN SELECT SUM(col1) FROM tbl1;

   ```

   返回结果如下：

   ```shell
   +-------------------------------------------------------------------------+
   | Query Plan                                                              |
   +-------------------------------------------------------------------------+
   | =================================================                       |
   | |ID|OPERATOR         |NAME|EST.ROWS|EST.TIME(us)|                       |
   | -------------------------------------------------                       |
   | |0 |SCALAR GROUP BY  |    |1       |3           |                       |
   | |1 |└─TABLE FULL SCAN|TBL1|1       |3           |                       |
   | =================================================                       |
   | Outputs & filters:                                                      |
   | -------------------------------------                                   |
   |   0 - output([T_FUN_SUM(T_FUN_SUM(TBL1.COL1))]), filter(nil), rowset=16 |
   |       group(nil), agg_func([T_FUN_SUM(T_FUN_SUM(TBL1.COL1))])           |
   |   1 - output([T_FUN_SUM(TBL1.COL1)]), filter(nil), rowset=16            |
   |       access([TBL1.COL1]), partitions(p0)                               |
   |       is_index_back=false, is_global_index=false,                       |
   |       range_key([TBL1.__pk_increment]), range(MIN ; MAX)always true,    |
   |       pushdown_aggregation([T_FUN_SUM(TBL1.COL1)])                      |
   +-------------------------------------------------------------------------+
   15 rows in set

   ```

在 Q1 查询返回结果中，除了 `SCALAR GROUP BY` 算子（0 号算子），还展示了以下执行算子：

- `TABLE FULL SCAN`：表示全表扫描。该算子属于 `TABLE SCAN` 算子，详细信息参见 [TABLE SCAN](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016219)。

上述 Q1 查询的执行计划展示中的 `Outputs & filters` 详细列出了 `SCALAR GROUP BY` 算子的输出信息如下：

| 信息名称 | 含义 | 示例说明 |
| --- | --- | --- |
| output | 该算子最终输出的列或表达式列表。 | `output([T_FUN_SUM(T_FUN_SUM(TBL1.COL1))])` 表示该算子输出的是表 `tbl1` 中 `col1` 列的总和。 |
| filter | 该算子需要应用的过滤条件（谓词）。 | `filter(nil)` 表示没有需要再额外过滤的行。 |
| rowset | 表示当前算子的向量化大小。 | `rowset=16` 表示当前算子的向量化大小为 16。 |
| group | 表示需要进行分组的列。 | `SCALAR GROUP BY` 算子用于不含 `GROUP BY` 子句的聚合查询，因此分组列为空，显示为 `group(nil)`。 |
| agg_func | 表示所涉及的聚合函数。 | Q1 查询是计算表 `tbl1` 的 `col1` 列数据之和，因此为 `T_FUN_SUM(TBL1.COL1)`。 |

## HASH GROUP BY

`HASH GROUP BY` 算子用于执行使用哈希算法进行的分组聚合操作。

### HASH GROUP BY 示例

1. 创建表 `tbl2`。

   ```shell
   obclient> CREATE TABLE tbl2 (col1 INT, col2 INT);

   ```
 2. Q2：对表 `tbl2` 按 `col1` 分组并计算每组 `col2` 的和，同时筛选出总和大于 2 的分组，查看该查询的执行计划。

   ```shell
   obclient> EXPLAIN SELECT SUM(col2)
       FROM tbl2
       GROUP BY col1
       HAVING SUM(col2) > 2;

   ```

   返回结果如下：

   ```shell
   +-------------------------------------------------------------------------------------+
   | Query Plan                                                                          |
   +-------------------------------------------------------------------------------------+
   | =================================================                                   |
   | |ID|OPERATOR         |NAME|EST.ROWS|EST.TIME(us)|                                   |
   | -------------------------------------------------                                   |
   | |0 |HASH GROUP BY    |    |1       |3           |                                   |
   | |1 |└─TABLE FULL SCAN|TBL2|1       |3           |                                   |
   | =================================================                                   |
   | Outputs & filters:                                                                  |
   | -------------------------------------                                               |
   |   0 - output([T_FUN_SUM(TBL2.COL2)]), filter([T_FUN_SUM(TBL2.COL2) > 2]), rowset=16 |
   |       group([TBL2.COL1]), agg_func([T_FUN_SUM(TBL2.COL2)])                          |
   |   1 - output([TBL2.COL1], [TBL2.COL2]), filter(nil), rowset=16                      |
   |       access([TBL2.COL1], [TBL2.COL2]), partitions(p0)                              |
   |       is_index_back=false, is_global_index=false,                                   |
   |       range_key([TBL2.__pk_increment]), range(MIN ; MAX)always true                 |
   +-------------------------------------------------------------------------------------+
   14 rows in set

   ```

在 Q2 查询返回结果中，除了 `HASH GROUP BY` 算子（0 号算子），还展示了以下执行算子：

上述 Q2 查询的执行计划展示中的 `Outputs & filters` 详细列出了 `HASH GROUP BY` 算子的输出信息如下：

| 信息名称 | 含义 | 示例说明 |
| --- | --- | --- |
| output | 该算子最终输出的列或表达式列表。 | `output([T_FUN_SUM(TBL2.COL2)])` 表示该算子输出的是表 `tbl2` 中 `col2` 列的总和。 |
| filter | 该算子需要应用的过滤条件（谓词）。 | `filter([T_FUN_SUM(TBL2.COL2) > 2])` 表示该算子上的过滤条件是分组后的列 `col2` 和大于 2。 |
| rowset | 表示当前算子的向量化大小。 | `rowset=16` 表示当前算子的向量化大小为 16。 |
| group | 表示需要进行分组的列。 | `group([TBL2.COL1])` 表示对 `tbl2` 表的 `col1` 列进行分组。 |
| agg_func | 表示所涉及的聚合函数。 | Q2 查询是计算表 `tbl2` 的 `col2` 列数据之和，因此为 `T_FUN_SUM(TBL2.COL2)`。 |

#### 说明

`HASH GROUP BY` 算子将会保证在执行时采用 `HASH` 算法进行分组。

## MERGE GROUP BY

`MERGE GROUP BY` 算子用于执行使用排序合并算法进行的分组聚合操作。当优化器选择此算法时，它通常需要其输入数据已按分组键排序。

### MERGE GROUP BY 示例

1. 创建表 `tbl3`。

   ```shell
   obclient> CREATE TABLE tbl3 (col1 INT, col2 INT);

   ```
 2. Q3：使用 Hint 强制优化器使用 `MERGE GROUP BY`，对表 `tbl3` 按 `col1` 分组并计算每组 `col2` 的和，同时筛选出总和大于 2 的分组，查看该查询的执行计划。

   ```shell
   obclient> EXPLAIN SELECT /*+NO_USE_HASH_AGGREGATION*/ SUM(col2)
       FROM tbl3
       GROUP BY col1
       HAVING SUM(col2) > 2;

   ```

   返回结果如下：

   ```shell
   +-------------------------------------------------------------------------------------+
   | Query Plan                                                                          |
   +-------------------------------------------------------------------------------------+
   | ===================================================                                 |
   | |ID|OPERATOR           |NAME|EST.ROWS|EST.TIME(us)|                                 |
   | ---------------------------------------------------                                 |
   | |0 |MERGE GROUP BY     |    |1       |3           |                                 |
   | |1 |└─PARTITION SORT   |    |1       |3           |                                 |
   | |2 |  └─TABLE FULL SCAN|TBL3|1       |3           |                                 |
   | ===================================================                                 |
   | Outputs & filters:                                                                  |
   | -------------------------------------                                               |
   |   0 - output([T_FUN_SUM(TBL3.COL2)]), filter([T_FUN_SUM(TBL3.COL2) > 2]), rowset=16 |
   |       group([TBL3.COL1]), agg_func([T_FUN_SUM(TBL3.COL2)])                          |
   |   1 - output([TBL3.COL1], [TBL3.COL2]), filter(nil), rowset=16                      |
   |       sort_keys([HASH(TBL3.COL1), ASC], [TBL3.COL1, ASC])                           |
   |   2 - output([TBL3.COL1], [TBL3.COL2]), filter(nil), rowset=16                      |
   |       access([TBL3.COL1], [TBL3.COL2]), partitions(p0)                              |
   |       is_index_back=false, is_global_index=false,                                   |
   |       range_key([TBL3.__pk_increment]), range(MIN ; MAX)always true                 |
   +-------------------------------------------------------------------------------------+
   17 rows in set

   ```

上述示例中，Q3 查询的执行计划展示中的 `Outputs & filters` 中详细列出了 `MERGE GROUP BY` 算子的信息，与 `HASH GROUP BY` 算子相比，其 `output`、`filter`、`group`、`agg_func` 等信息的含义是相同的。最大的区别在于执行时选择的分组算法不一样，且由于 `MERGE GROUP BY` 需要输入数据有序，而 `TABLE FULL SCAN` 返回的是无序结果，因此优化器在 `MERGE GROUP BY` 算子之下分配了一个 `PARTITION SORT`（或 `SORT`）算子来对数据进行排序。

`PARTITION SORT`：表示分区排序。该算子属于 `SORT` 算子，详细信息参见 [SORT](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016207)。

#### 注意

`NO_USE_HASH_AGGREGATION` 和 `USE_HASH_AGGREGATION` 的 Hint 可以用于控制 `GROUP BY` 算子选择何种算法进行分组。

  上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
