LIMIT不能设太大,否则会触发ORA-04030导致PGA内存耗尽崩溃;安全值需按字段类型区分:纯数值/字符串推荐500,含CLOB/BLOB须≤100,RAC环境下更需严控;必须写在FETCH末尾并配合EXIT WHEN集合为空判断,且优先选用NESTED TABLE类型。

为什么LIMIT不能随便设大
设太大不是“更快”,是直接触发 ORA-04030:PGA 内存耗尽崩溃。BULK COLLECT 默认不限行,查 50 万行 × 1.2KB/行 ≈ 600MB PGA 占用,远超多数实例单会话限制(200–500MB)。这不是慢,是会话直接挂掉。
LIMIT 的安全取值范围怎么定
不是凭经验拍脑袋,得看字段类型和场景:
- 纯数值/字符串字段:推荐
LIMIT 500,19c 实测在多数 OLTP 场景下吞吐与内存占用最平衡 - 含
CLOB或BLOB字段:必须 ≤100,大对象按块加载,内存放大效应极强 - RAC 环境下:别信“我这台服务器内存大”,PGA 是共享资源,一个游标吃光会影响所有会话
LIMIT 必须写在哪、怎么配合退出
LIMIT 只能写在 FETCH 语句末尾,比如:FETCH c_emp BULK COLLECT INTO l_tab LIMIT 500。写在 SELECT 或 OPEN 里无效。
退出循环不能只靠 %NOTFOUND —— 它在批量 FETCH 下不可靠。必须显式检查:EXIT WHEN l_tab.COUNT = 0。
另外,l_tab 来自 BULK COLLECT 且源 SQL 含绑定变量时,若变量值导致结果为空,集合是 NULL 而非空集合,直接 FORALL 会报 ORA-06531。得先判空:IF l_tab IS NOT NULL AND l_tab.COUNT > 0 THEN FORALL...
集合类型选错会让LIMIT失效
不是所有集合都能传给 FORALL。用错类型(比如该用嵌套表却用了 VARRAY),会导致批量逻辑退化成逐行执行,或者直接报 ORA-06502。
关键区别:
-
VARRAY有固定上限,索引连续,LIMIT超过声明容量会报ORA-06532 -
NESTED TABLE动态可扩,但未初始化就访问元素会报ORA-06530;SQL 层可用TABLE()函数引用,VARRAY不行
批量处理一律优先选 NESTED TABLE 类型,声明时不用指定上限,也兼容 FORALL 和后续 SQL 操作。


















