PRAGMA INLINE 在 Oracle 19c 中有效但非强制内联,需 PLSQL_OPTIMIZE_LEVEL=3 才可能生效;内联失败常见于含 DBMS_OUTPUT、RESULT_CACHE、%ROWTYPE、动态 SQL 的函数,且 FORALL/BULK 场景下收益低。
PRAGMA INLINE 在 Oracle 19c 中仍有效,但它的实际效果高度依赖编译器优化级别和调用上下文。直接加 PRAGMA INLINE 不等于一定内联,更不是“函数调用变快”的万能开关。
PLSQL_OPTIMIZE_LEVEL=3 是内联生效的前提
oracle 19c 默认 plsql_optimize_level 是 2,此时 pragma inline 必须显式声明才可能触发内联;设为 3 后,编译器会自动评估所有子程序调用是否适合内联——包括无 pragma 的函数。
- 确认当前值:
SELECT plsql_optimize_level FROM user_plsql_object_settings WHERE name = 'YOUR_PROCEDURE_NAME'; - 强制启用(建对象时):
ALTER PROCEDURE your_proc COMPILE PLSQL_OPTIMIZE_LEVEL=3; - 全局设置(谨慎):
ALTER SYSTEM SET PLSQL_OPTIMIZE_LEVEL=3 SCOPE=BOTH;,但会影响所有新编译对象的稳定性
内联失败的常见信号:执行计划里还出现 FUNCTION SCAN
即使 PRAGMA INLINE('YES') 写了、PLSQL_OPTIMIZE_LEVEL=3 也设了,如果函数体里含以下任一结构,Oracle 19c 仍会放弃内联:
- 调用了
DBMS_OUTPUT.PUT_LINE或其他非确定性内置过程 - 函数声明了
RESULT_CACHE—— 缓存机制与内联逻辑冲突 - 函数参数类型含
%ROWTYPE或嵌套表,且未做简化包装 - 函数内部有
EXECUTE IMMEDIATE或动态 SQL
验证方式:对调用该函数的 SQL 执行 EXPLAIN PLAN,若 PLAN_TABLE.OPERATION 出现 FUNCTION SCAN,说明没内联成功。
别在 FORALL 或 BULK COLLECT 循环里依赖内联函数
19c 的批量操作路径(如 FORALL i IN 1..my_tab.COUNT)本身已绕过 PL/SQL 引擎调度开销,此时再把计算逻辑内联进去,收益极小,反而可能因函数体膨胀导致 PGA 使用突增。
- 更稳妥做法:把函数逻辑提前拆解成纯 SQL 表达式,例如用
CASE WHEN替代简单分支函数 - 若必须复用函数,确保它被定义为
DETERMINISTIC,这样在单次 SQL 执行中相同输入只算一次 - 警惕
simple_integer类型函数被内联后溢出不报错——这在批量场景下容易静默污染结果











