Oracle 19c的PL/SQL引擎本身无新增语法或运行时优化,性能提升源于底层SQL执行层更稳定准确;关键需确保BULK COLLECT与FORALL路径稳定、集合数据预校验、统计信息更新并配置直方图。

Oracle 19c 的 PL/SQL 引擎本身没有新增语法、类型或运行时优化机制,所谓“性能提升”不是来自 PL/SQL 编译器或解释器变快了,而是依赖底层 SQL 执行层更稳、更准——前提是你的 PL/SQL 正确调用并适配这些变化。
PL/SQL 集合处理仍靠 BULK COLLECT + FORALL,但稳定性增强
19c 没改 BULK COLLECT 语法,也没加新集合类型,但它修复了 RAC 环境下游标缓存不一致导致的批量中断;更重要的是,当 WHERE col IN (SELECT * FROM TABLE(my_array)) 这类写法出现时,优化器对集合大小的估算更可靠——但这只在统计信息更新且带直方图的前提下生效。
常见踩坑点:
-
my_tab.COUNT前没判空:若BULK COLLECT INTO my_tab的源 SQL 返回空结果,my_tab是NULL而非空集合,直接FORALL会报ORA-06531 - 用
FORALL i IN INDICES OF my_tab但没预校验数据有效性:比如my_tab(i).status可能为NULL或非法值,导致 DML 失败后才暴露问题 - 盲目开启
_optimizer_use_feedback=TRUE:19c 默认关掉它,就是为避免首次执行采样偏差引发批量计划回退到单行驱动
SQL 宏(SQL_MACRO)可减少硬解析,但不改变 PL/SQL 执行模型
SQL_MACRO 是 19.7+ 支持的特性,它让 SQL 片段变成参数化模板,嵌入在 SELECT、FROM 或 WHERE 中复用。它不加速 PL/SQL 本身,但能减少因拼接 SQL 导致的硬解析次数——尤其当你在 PL/SQL 中大量用 EXECUTE IMMEDIATE 时。
关键限制:
- 宏展开发生在解析阶段,不是运行时;所以不能用 PL/SQL 变量动态控制宏逻辑
- 宏体里不能引用本地 PL/SQL 变量,只能引用 SQL 上下文可见的对象(如表、列、绑定变量)
- 若宏内含复杂子查询,每次调用仍需完整解析,不会自动缓存执行计划
IF [NOT] EXISTS 让 DDL 更安全,但和性能无关
CREATE TABLE IF NOT EXISTS 这类语法从 19.28 开始支持,它只是避免“对象已存在”错误,让部署脚本幂等。它不加快 PL/SQL 执行,也不影响游标共享或绑定变量行为。
注意两个实际约束:
- 不能和
OR REPLACE同时用:CREATE OR REPLACE TABLE IF NOT EXISTS会报错 - 它只抑制错误,不跳过实际操作:如果表存在且结构不同,
IF NOT EXISTS不做任何事,也不会尝试兼容性检查
真正影响 PL/SQL 性能的,从来不是“有没有新函数”,而是你是否让 BULK COLLECT 拿到稳定执行路径、是否让 FORALL 绑定的数据通过预校验、是否用对了统计信息粒度——这些细节在 19c 里变得更敏感,也更容易出错。



















