在传统的数据库开发过程中,很多开发者习惯于将业务逻辑写在 PL/SQL 中,借助存储过程、函数来实现数据计算和处理。然而,PL/SQL 与 SQL 查询之间的切换往往会带来额外的性能消耗。Oracle 23ai 中的 SQL Transpiler 就是为了解决这一问题而设计的。通过自动转换 PL/SQL 函数为 SQL 表达式,数据库引擎可以直接在 SQL 级别处理计算逻辑,从而降低函数调用的额外开销,同时还使查询优化器能够更好地优化执行计划。
具体来说,SQL Transpiler 能够在无需用户过多干预的情况下,将在 SQL 查询中调用的某些 PL/SQL 函数进行转换。这样一来,原本复杂的函数调用就可以被简化为标准的 SQL 算术运算或其他 SQL 表达式,大大提升了 SQL 查询的执行速度和整体响应能力。
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 的优势在于其能够简化对存储过程和函数的调用逻辑,尤其是在数据量较大或查询复杂度较高的情况下,其优化效果尤为明显。
初始化数据:
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 时:
select id, col1, col2 from test1where add_numbers(col1, col2) = 300;select * from dbms_xplan.display_cursor();SQL_ID f38z6t91fvrun, child number 0-------------------------------------select id, col1, col2 from test1where add_numbers(col1, col2) = 300Plan 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 来启用这一功能:
alter session set sql_transpiler = 'ON';select id, col1, col2 from test1where 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 test1where add_numbers(col1, col2) = 300Plan 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
。这一转换有效消除了函数调用的额外成本,从而有助于简化执行计划和提高查询性能。





