“窗口”也称为FRAME,OceanBase 同时支持 ROWS 与 RANGE 两种 FRAME 语义,前者是基于物理行偏移的窗口,后者则是基于逻辑值偏移的窗口。

目前 OceanBase 支持以下分析函数:

  • SUM

  • MIN

  • MAX

  • AVG

  • GROUP_CONCAT**

  • LISTAGG*

  • RANK

  • DENSE_RANK

  • PERCENT_RANK

  • CUME_DIST

  • LAST_VALUE

  • NTH_VALUE

  • NTILE

  • LEAD

  • LAG

执行计划

OceanBase 分析函数的相应算子是: WINDOW FUNCTION,该算子依赖下层算子的输出按分区 + 排序键有序,所以在必要时会分配排序算子。

排序消除

如果优化阶段已经知道下层输出是有序的,则不会分配排序算子((tenant_id,table_id)为__all_root_table 主键前缀)

计算合并

当同时存在多个分析函数时,如果存在可以共享一个序的子集,子集内所有函数会在同一个算子里计算而不是拆到多个算子,这样可以有效减少内存开销和边界判断。

如下例所示,row_number() 与 rank() 两个分析函数的计算可以共用同一个排序的输出,因此,只会分配一个 sort 节点:

落盘

分析函数的计算也支持执行期的落盘操作,其逻辑与排序操作符的落盘逻辑一致。

两种兼容模式下的差异

虽然 MySQL 模式和 Oracle 模式下支持的分析函数基本一样,但即使对于同一个分析函数,也存在着语法、约束检查和实现上的诸多差异。

  • Oracle 模式下不支持命名窗口功能;

  • 窗口函数如 NTH_VALUE、LEAD、LAG 的某些参数在 MySQL 模式下仅接受整型,但在 Oracle 模式下可以接受能转换成整型的其它类型;

  • Oracle 模式下窗口函数会多出合法性检查;如 NTILE、LISTAGG 要求窗口函数参数来自 partition by 项,再如FIRST_VALUE、LAST_VALUE 指定了窗口时必须同时进行排序;