Oracle Database 23ai 中的 SQL Transpiler

在 Oracle Database 23ai 中,引入了一项非常有价值的功能 —— SQL Transpiler。该功能旨在通过将 PL/SQL 函数自动转换为 SQL 表达式,来减少 SQL 查询中函数调用的开销,使得数据库在处理复杂查询时能够更高效地利用底层执行引擎,提高查询执行效率,从而在复杂数据处理场景下获得更好的性能表现。无论是在单实例环境还是在多实例(如 RAC)环境中,该功能都为开发者提供了灵活的性能调优工具。对于那些依赖大量函数调用的应用程序来说,合理利用 SQL Transpiler 不仅能降低系统资源消耗,还能显著提升整体响应速度,是一个非常值得关注的优化特性。

功能优势

在传统的数据库开发过程中,很多开发者习惯于将业务逻辑写在 PL/SQL 中,借助存储过程、函数来实现数据计算和处理。然而,PL/SQL 与 SQL 查询之间的切换往往会带来额外的性能消耗。Oracle 23ai 中的 SQL Transpiler 就是为了解决这一问题而设计的。通过自动转换 PL/SQL 函数为 SQL 表达式,数据库引擎可以直接在 SQL 级别处理计算逻辑,从而降低函数调用的额外开销,同时还使查询优化器能够更好地优化执行计划。

具体来说,SQL Transpiler 能够在无需用户过多干预的情况下,将在 SQL 查询中调用的某些 PL/SQL 函数进行转换。这样一来,原本复杂的函数调用就可以被简化为标准的 SQL 算术运算或其他 SQL 表达式,大大提升了 SQL 查询的执行速度和整体响应能力。

参数说明

Oracle Database 为 SQL Transpiler 提供了一个名为 SQL_TRANSPILER 的初始化参数。该参数可以在会话级别或系统级别进行设置,以便灵活控制 SQL Transpiler 的启用状态。

当该参数设置为 ON 时,Oracle 数据库会自动尝试将存储在数据库中的 PL/SQL 函数转换为 SQL 表达式;而设置为 OFF 则表示禁用这一转换功能。在多实例环境中,如 Oracle RAC,不同的实例可以根据实际需求分别启用或禁用 SQL Transpiler,从而实现灵活的资源调度和负载均衡。

转换机制

SQL Transpiler 主要针对那些在 SQL 查询中经常被调用的 PL/SQL 函数。通过分析函数内部的逻辑,系统会判断是否可以将其直接转换为 SQL 运算。例如,如果函数内仅包含简单的算术运算或字符串处理,SQL Transpiler 就会将其转换为相应的 SQL 表达式。这样不仅能够减少上下文切换带来的性能损耗,还能使查询计划更加简洁明了,便于数据库优化器进行更高效的执行计划生成。

在转换过程中,Oracle 会对函数内部的表达式进行语义分析和安全性检查,确保转换后的 SQL 表达式在逻辑上与原有的 PL/SQL 函数保持一致,并且不会引入潜在的安全隐患或错误。

示例

在实际应用中,SQL Transpiler 的优势在于其能够简化对存储过程和函数的调用逻辑,尤其是在数据量较大或查询复杂度较高的情况下,其优化效果尤为明显。

初始化数据:

代码语言:javascript代码运行次数:0运行复制
drop table if exists test1;
create table t1 (
  id    number,
  col1  number,
  col2  number
);
insert into t1 (id, col1, col2)
values (1, 1, 2), (2, 10, 20), (3, 100, 200);
commit;

以下示例展示了在未启用和启用 SQL Transpiler 时查询执行计划的对比:

未启用 SQL Transpiler 时:

代码语言:javascript代码运行次数:0运行复制
select id, col1, col2 from   test1
where  add_numbers(col1, col2) = 300;


select * from   dbms_xplan.display_cursor();

SQL_ID  f38z6t91fvrun, child number 0
-------------------------------------
select id, col1, col2 from   test1 
where  add_numbers(col1, col2) = 300

Plan hash value: 4122059633

---------------------------------------------------------------------------
| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| TEST1 |     1 |    39 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("ADD_NUMBERS"("COL1","COL2")=300)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

在上述示例中,查询中直接调用了 ADD_NUMBERS 函数,因此在执行计划中仍然可以看到对该函数的调用,从而增加了额外的计算开销。

启用 SQL Transpiler 后:

为了验证 SQL Transpiler 的效果,我们可以通过修改会话参数为 ON 来启用这一功能:

代码语言:javascript代码运行次数:0运行复制
alter session set sql_transpiler = 'ON';

select id, col1, col2 from  test1
where  add_numbers(col1, col2) = 300;

select * from   dbms_xplan.display_cursor();

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID  dcttgua9qy5x4, child number 0
-------------------------------------
select id, col1, col2 from  test1 
where  add_numbers(col1, col2) = 300

Plan hash value: 4122059633

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| TTEST11   |     1 |    39 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("COL1"+"COL2"=300)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


22 rows selected.

SQL>

可以看到,启用 SQL Transpiler 后,原来通过函数 ADD_NUMBERS 实现的计算逻辑已经被转换为直接的 SQL 表达式 "COL1" + "COL2"=300。这一转换有效消除了函数调用的额外成本,从而有助于简化执行计划和提高查询性能。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-03-25,如有侵权请联系 cloudcommunity@tencent 删除database函数性能oraclesql