/+ APPEND /触发直接路径插入而非优化器提示,需满足无启用触发器、非IOT、不被外键引用、同一事务未执行常规DML等硬性条件,否则静默降级或报ORA-12838。

/*+ APPEND */ 不是“加个提示就变快”,它触发的是 Oracle 的直接路径插入机制,必须满足硬性条件才能生效;否则会静默退化为常规插入,或直接报 ORA-12838。
为什么 /*+ APPEND */ 有时没效果甚至报错
根本原因是:/*+ APPEND */ 不是优化器提示(optimizer hint),而是执行路径开关(execution path directive)。它强制走直接路径插入(direct-path insert),而该路径有不可妥协的约束:
- 表上不能有启用的触发器 —— 查
SELECT triggers_enabled FROM user_tables WHERE table_name = 'T',若为'ENABLED',需先ALTER TABLE t DISABLE ALL TRIGGERS - 不能是索引组织表(IOT)—— 查
iot_type字段,非NULL则不支持 - 不能被外键约束引用(即该表不能是子表)—— 查
user_constraints中constraint_type = 'R'且r_constraint_name指向本表 - 同一事务中不能先执行过常规 DML(如
INSERT INTO t VALUES (...))—— 否则后续/*+ APPEND */会报ORA-12838: cannot read/modify an object after modifying it in parallel - 当前会话在插入后、提交前,连
SELECT COUNT(*) FROM t都会触发 ORA-12838
INSERT /*+ APPEND */ 和 INSERT /*+ APPEND_VALUES */ 怎么选
两者都走直接路径,但适用场景和解析行为完全不同:
-
INSERT /*+ APPEND */ SELECT ...:适合从子查询加载大批量数据(≥1000 行),SQL 解析开销小,推荐作为主力用法 -
INSERT /*+ APPEND_VALUES */:Oracle 11g+ 引入,专为少量VALUES设计(≤100 行),写法简洁,例如:INSERT /*+ APPEND_VALUES */ INTO t VALUES (1,'a'), (2,'b'), (3,'c') - ⚠️ 千万别用
APPEND_VALUES插上千行VALUES列表——SQL 文本过长会导致硬解析失败,或自动降级为常规路径;此时应改用SELECT ... FROM (VALUES ..., ..., ...)或拆批 -
APPEND_VALUES不支持绑定变量,所有值必须是字面量;APPEND+SELECT则完全支持绑定
插入后查不到数据?不是没成功,是没提交 + 没绕过缓存
直接路径插入的数据写入高水位线(HWM)之上,不经过 Buffer Cache,所以:
- 未
COMMIT前,其他会话查不到;本会话查会报 ORA-12838 - 即使已
COMMIT,某些客户端(如旧版 SQL Developer)可能因缓存统计信息显示COUNT(*) = 0 - 验证是否真插入成功,不要只信
SELECT COUNT(*),优先用:SELECT /*+ FULL(t) */ COUNT(*) FROM t(强制全表扫描,跳过统计缓存) - 也可查物理位置:
SELECT dbms_rowid.rowid_block_number(rowid) FROM t WHERE ROWNUM = 1,对比 HWM 前后块号是否明显增大
想更快?得配 NOLOGGING,但得担风险
仅 /*+ APPEND */ 在归档模式下仍会生成大量重做日志;要极致提速,必须配合 NOLOGGING:
- 先执行:
ALTER TABLE t NOLOGGING(注意:此操作本身需日志,且影响备份恢复能力) - 再执行:
INSERT /*+ APPEND */ ...,此时重做量极小(仅数据字典变更) - 插入完成后,建议立即
ALTER TABLE t LOGGING恢复归档安全 - ⚠️ NOLOGGING 操作无法通过归档日志恢复——如果表损坏且无备份,这部分数据永久丢失
- 非归档模式下,
/*+ APPEND */本身就不生成块级重做,无需额外设 NOLOGGING
最常被忽略的一点:直接路径插入会持有一个表级排他锁(TM lock mode 6),整个插入过程期间,其他会话无法对该表执行任何 DML(INSERT/UPDATE/DELETE),只允许 SELECT。如果你在 OLTP 核心表上跑批量加载,这个锁会成为隐形阻塞源——别只盯着“快”,得看它卡住了谁。


















