OceanBase V4.2 特性解析:用Values Statement 语法进行SQL优化

1. 背景

你是否也遭遇过这样的场景:在输出多行多列表格数据时,却受限于只能依赖多 UNION ALL 语句来实现。在实际的工程应用中,我们也观察到有些用户程序生成的 SQL 语句中含有大量的 UNION ALL,这种结构的 SQL 对于 OceanBase 数据库的内核来说并不友好,常常会导致内存和 CPU 的使用率显著上升。

复制代码
OceanBase> SELECT 1, 2, 3 FROM DUAL UNION ALL SELECT 4, 5, 6 FROM DUAL UNION ALL SELECT 7, 8, 9 FROM DUAL; 
+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
|        7 |        8 |        9 |
+----------+----------+----------+

OceanBase 在 V4.2.1 版本实现了 Values Statement 语法,它返回一行或多行作为表,可用作独立的 SQL 语句。换句话说,Values Statement提供了一种表数据的构造方式。例如:

复制代码
OceanBase> VALUES ROW(1, 2, 3), ROW(4, 5, 6), ROW(7, 8, 9);
+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
|        7 |        8 |        9 |
+----------+----------+----------+

2. 语法

其标准语法如下:

复制代码
VALUES row_constructor_list [ORDER BY column_designator] [LIMIT number]

row_constructor_list:
    ROW(value_list)[, ROW(value_list)][, ...]

value_list:
    value[, value][, ...]

column_designator:
    column_index

Values Statement 语句由 VALUES 关键字组成,后跟一个或多个行构造函数的列表,以逗号分隔。行构造函数由 ROW() 行构造函数子句组成,该子句带有一个包含在括号中的一个或多个标量值的值列表。值可以是任何 MySQL 数据类型或标量值的表达式。最终组成多列多行的一张"表","表"的列默认指定了隐式命名:column_0、column_1、column_2 等,始终以 0 开头。如下面的一个简单例子:

复制代码
OceanBase> VALUES ROW(1, -2, 3), ROW(5, 7, 9), ROW(4, 6, 8);
+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |       -2 |        3 |
|        5 |        7 |        9 |
|        4 |        6 |        8 |
+----------+----------+----------+

Values Statement 一列中允许使用不同类型的数值,如下所示:

复制代码
OceanBase> VALUES ROW(1, -2, 'oceanbase'), ROW('a', 5, 'mysql'), ROW('222asda', 8, date'2020-12-01');
+----------+----------+--------------+
| column_0 | column_1 | column_2     |
+----------+----------+--------------+
| 1        |       -2 | oceanbase    |
| a        |        5 | mysql        |
| 222asda  |        8 | 2020-12-01   |
+----------+----------+--------------+

3. 使用场景

  1. 创建临时表格数据,可以使用一个表格数据替换多 UNION ALL。

例如:

复制代码
SELECT 1, 2, 3 UNION ALL SELECT 4, 5, 6 UNION ALL SELECT 7, 8, 9; 
# 使用 Values Statement 表示临时表格数据为:
VALUES ROW(1, 2, 3), ROW(4, 5, 6), ROW(7, 8, 9);

例如:

复制代码
CREATE TABLE t1 (type_a int, type_b int, type_c int);
SELECT CASE WHEN V.c1 = 1 AND t1.type_a = 1 THEN 'type_a'
            WHEN V.c1 = 2 AND t1.type_b = 1 THEN 'type_b'
            WHEN V.c1 = 3 AND t1.type_c = 1 THEN 'type_c'
            ELSE NULL
       END AS col_type
       FROM t1, (SELECT 1 AS c1 UNION ALL SELECT 2 UNION ALL SELECT 3) V;
# 使用 Values Statement 表示临时表格数据为:
SELECT CASE WHEN V.column_0 = 1 AND t1.type_a = 1 THEN 'type_a'
            WHEN V.column_0 = 2 AND t1.type_b = 1 THEN 'type_b'
            WHEN V.column_0 = 3 AND t1.type_c = 1 THEN 'type_c'
            ELSE NULL
       END AS col_type
       FROM t1, (VALUES ROW(1), ROW(2), ROW(3)) V;

2、快速创建表或视图。

例如:

复制代码
CREATE TABLE t1 AS VALUES ROW(1, 2, 3), ROW(4, 5, 6), ROW(7, 8, 9);
CREATE VIEW v1 AS VALUES ROW(1, 2, 3), ROW(4, 5, 6), ROW(7, 8, 9);

4. Values Statement 能力和展望

除此之外,OceanBase V4.2.x 会将 Values Statement 用于优化器内部改写,优化大 IN/UNION 场景的执行性能,降低 SQL 资源消耗。例如:

1、将谓词中IN做改写,将过滤谓词变成了semi join,进一步改写为inner join,有了更多优化改写 的可能性。

复制代码
SELECT * FROM t1 WHERE t1.c1 IN (1, 2, 3, 4);
# 内核改写为:
SELECT * FROM t1 SEMI JOIN (VALUES ROW(1), ROW(2), ROW(3), ROW(4)) V WHERE t1.c1 = V.column_0;

2、对于大量的常量union all/union 也能够改写

复制代码
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
# 内核改写为:
VALUES ROW(1, 2, 3)
相关推荐
OceanBase数据库官方博客6 天前
OceanBase DataStudio:让 AI数据生产从拼装走向一体化(技术解析与
人工智能·oceanbase
数据库小学妹6 天前
国产数据库选型技术指南:五大主流路线对比与Oracle迁移策略分析
分布式数据库·信创数据库·oracle迁移·国产数据库选型·集中式数据库
数据库小学妹7 天前
分布式数据库架构怎么选?三种路线对比+迁移避坑指南
数据库·分布式·分布式数据库·数据库架构·数据迁移·数据库选型
Database_Cool_8 天前
阿里云 PolarDB-X vs OceanBase 国产分布式数据库深度对比
分布式·阿里云·oceanbase
AllData公司负责人10 天前
数据库同步平台|AIIData数据中台实现OceanBase、达梦数据库、OpenGauss、人大金仓、Hive、TDengine 一键接入Doris
大数据·数据库·hive·mysql·oceanbase·tdengine
OceanBase数据库官方博客12 天前
OceanBase AI 时代,数据库的变与不变(技术解析与实践)
数据库·人工智能·oceanbase
程序员cxuan13 天前
OceanBase 为什么要做 AI 数据库?
数据库·人工智能·大模型·llm·oceanbase
OceanBase数据库官方博客13 天前
基于 OceanBase 湖库一体架构,构建 AI 时代的数据基础设施
人工智能·架构·oceanbase
OceanBase数据库官方博客13 天前
OceanBase Lakebase 架构解析:独立部署与智能叠加层模式的技术实践
架构·oceanbase