OpenMLDB SQL 与标准 SQL 的主要差异
本文将 OpenMLDB SQL 的主要使用方式(SELECT 查询语句)与标准 SQL (以 MySQL 支持的语法为例)进行比较,让有 SQL 使用经验的开发者快速上手 OpenMLDB SQL。
面向 OpenMLDB 版本:>= v0.7.1
支持总览
下表根据 SELECT 语句元素对 OpenMLDB SQL 在三种执行模式下(关于执行模式参考 使用流程和执行模式 — OpenMLDB documentation)与标准 SQL 整体性的差异做了汇总。OpenMLDB SQL 目前部分兼容标准 SQL,但考虑实际业务场景需求新增了部分语法,下表加粗部分为新增语法。注:✓ 表示支持该语句,✕ 表示不支持。
差异详解
差异维度
与标准 SQL 比较,OpenMLDB SQL 的差异性主要会从三个维度进行说明:
执行模式:在三种不同执行模式下(离线模式,在线预览模式,在线请求模式),不同的 SQL 的支持程度不一样,需要分开考察。普遍的,为了最终可以让 SQL 实现实时计算,最终需要上线的业务 SQL 需要符合在线请求模式的要求。
子句组合:不同子句的组合会带来额外的限制,下文描述形式 A 应用于 B,表示 A 子句在 B 子句的结果上运行。比如 LIMIT 应用于 WHERE,则其 SQL 类似为:
SELECT * FROM (SELECT * FROM t1 WHERE id >= 2) LIMIT 2
。下文中的“表引用”是指
FROM TableRef
,不是 subquery 也不是带有 join/union 的复杂 FROM 子句。特殊限制:不归于以上两类的特殊限制,会进行单独说明,一般是由于功能支持不完善或者程序已知问题所引起。
扫描限制的配置
为了避免用户误操作而影响到在线性能,OpenMLDB 有相关参数来限制在离线模式和在线预览模式下的全表扫描次数。如果打开了这些参数的限制,将会导致部分涉及到多个记录扫描的操作(比如 SELECT *, 聚合操作等)可能出现结果截断,而最终产生错误结果。注意,这些参数不会影响到在线请求模式的结果正确性。
相关参数会在 tablet 配置文件 conf/tablet.flags 里进行配置,详见文档 配置文件 — OpenMLDB documentation 。影响到扫描限制的参数为:
最大扫描条数
--max_traverse_cnt
最大扫描 key 的个数
--max_traverse_pk_cnt
返回的结果大小限制
--scan_max_bytes_size
预计在 v0.7.3 以及以后版本中,以上参数的默认值都为 0,即不做相关限制。之前的版本需要注意相关参数的设置。
WHERE 子句
LIMIT 子句
后面跟一个 INT literal, 不支持其它表达式,表示返回数据的最大行数。LIMIT 不支持上线。
WINDOW 子句
WINDOW 子句和 GROUP BY & HAVING 子句不支持同时使用。上线时 WINDOW 的输入表必须是物理表或者对物理表的简单列筛选和 last join 拼接(简单列筛选为 select list 只有列引用或者列的重命名,没有其它表达式),具体支持参照下表,未列出情况均为不支持。
特殊限制:
在线请求模式下,WINDOW 的输入是 LAST JOIN 或者子查询内的 LAST JOIN, 注意窗口的定义里 partition by & order by 的列都必须来自 JOIN 最左边的表。
GROUP BY & HAVING 子句
GROUP BY 语句,目前仍为实验性功能,仅支持输入表是一张物理表, 其它情况不支持。GROUP BY 不支持上线。
JOIN 子句(LAST JOIN)
OpenMLDB 仅支持 LAST JOIN 一种 JOIN 语法,详细描述参考扩展语法的 LAST JOIN 部分。JOIN 有左右两个输入,在线请求模式下,支持两个输入为物理表,或者特定的子查询,详见表格,未列出情况不支持。
特殊限制:
关于特定子查询的 LAST JOIN 上线,还有额外要求,详见上线要求 。
在线预览模式下不支持 LAST JOIN, 见 issue https://github.com/4paradigm/OpenMLDB/issues/2976。
WITH 子句
OpenMLDB (>= v0.7.2) 支持非递归的 WITH 子句。WITH 子句等价于其它子句应用于子查询时的语义,WITH 语句的支持情况,可参照其对应子查询写法下,上述表格的说明。
特殊限制:
无
聚合函数
聚合函数可应用于全表或窗口。三种模式下均支持窗口聚合查询;全表聚合查询仅在在线预览模式下支持,离线和在线请求模式不支持。
特殊限制:
OpenMLDB v0.6.0 开始支持在线预览模式的全表聚合,但注意所描述的 扫描限制配置。
OpenMLDB 有自己的聚合函数列表,请查看产品文档具体查询所支持的函数 OpenMLDB 内置函数。
扩展语法
OpenMLDB 主要对 WINDOW 以及 LAST JOIN 语句进行了深度定制化开发,本节将对这两个语法进行详细说明。
WINDOW 子句
在 OpenMLDB 里使用到的一个典型的 WINDOW 语句一般会包含以下元素:
数据定义:通过
PARTITION BY
定义窗口内数据数据排序:通过
ORDER BY
定义窗口内数据排序范围定义:通过
PRECEDING
,CURRENT ROW
,UNBOUNDED
定义时间延展方向范围单位:通过
ROWS
,ROWS_RANGE
定义窗口滑动范围的单位窗口属性:OpenMLDB 特有的窗口属性定义,包括
MAXSIZE
,EXECLUDE CURRENT_ROW
,EXCLUDE CURRENT_TIME
,INSTANCE_NOT_IN_WINDOW
多表定义:通过扩展语法
WINDOW ... UNION
定义是否需要进行跨表数据源拼接关于 WINDOW 详细语法,请参考 WINDOW 文档。
特殊限制
在线预览模式或者离线模式下,WINDOW 的输入是 LIMIT 或者 WHERE 子句,得到的计算结果可能不正确, 不建议使用。
窗口定义举例
定义 ROWS 类型窗口,窗口范围是前 1000 行到当前行:
定义 ROWS_RANGE 类型窗口,窗口范围是当前行前 10 秒的所有行,以及当前行:
定义一个 ROWS 类型窗口,窗口范围是前 1000 行到当前行。 除了当前行以外窗口内不包含当前时刻的其他数据:
定义一个 ROWS_RANGE 类型窗口,窗口范围为当前时间到过去 10 秒,但是不包含当前请求行:
匿名窗口:
WINDOW ... UNION 举例
在实际开发中,较多的应用的数据是存放在多个表格中,在这种情况下,一般会使用 WINDOW ... UNION 的语法进行跨表的聚合操作。请参考教程 跨表特征开发教程
LAST JOIN 子句
关于 LAST JOIN 详细语法规范,请参考 LAST JOIN 文档。
LAST JOIN 举例
了解更多
如果想进一步了解 OpenMLDB 或者参与社区技术交流,可以通过以下渠道获得相关信息和互动。
OpenMLDB GitHub 主页
https://github.com/4paradigm/OpenMLDB
OpenMLDB 微信交流群
评论