PARTITION RANGE ALL 表明分区裁剪彻底失效,需检查执行计划中 pstart/pstop 是否为 ALL 或全范围、WHERE 中分区键是否裸写、统计信息是否准确、物化视图或索引是否对齐。

执行计划里出现 PARTITION RANGE ALL,就说明分区裁剪彻底失效了——不是“可能没走”,而是明确扫了所有分区。
看执行计划有没有 pstart 和 pstop
这是最直接的判断依据。用 EXPLAIN PLAN FOR 执行查询后查 PLAN_TABLE,重点盯这两列:
- 如果
pstart和pstop都是ALL或数值范围覆盖全部分区(比如 1 到 128),说明没裁剪 - 如果显示具体数字(如
pstart=5 pstop=5),才是精准落到单一分区 -
OPERATION列出现PARTITION RANGE SINGLE或ITERATOR才算成功;TABLE ACCESS FULL却没带分区信息,基本等于白分
检查 WHERE 条件里分区键是否“裸奔”
分区键必须以原始列形式出现在谓词中,任何加工都会断掉裁剪链:
- ❌
WHERE TRUNC(log_time) = DATE '2026-07-01'—— 函数包裹直接废掉裁剪能力 - ❌
WHERE log_time = '2026-07-01'—— 字符串隐式转 DATE,类型不匹配 - ❌
WHERE log_time >= TO_DATE(:bind_var, 'YYYY-MM-DD')—— 绑定变量类型若是VARCHAR2,而非DATE,同样失效 - ✅ 正确写法:
WHERE log_time >= DATE '2026-07-01'或WHERE log_time BETWEEN DATE '2026-07-01' AND DATE '2026-07-31'
确认统计信息是否完整且有效
优化器靠统计信息估算各分区数据量,如果 DBA_TAB_PARTITIONS.NUM_ROWS 是 NULL 或严重失真,它会认为“扫一个和扫十个差不多”,干脆放弃裁剪:
- 查分区行数:
SELECT partition_name, num_rows, blocks FROM dba_tab_partitions WHERE table_name = 'YOUR_TABLE' - 缺失或异常?运行收集命令:
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCHEMA', tabname => 'YOUR_TABLE', granularity => 'ALL') - 特别注意:批量插入、
TRUNCATE PARTITION后必须重收集,否则统计信息立刻过期
物化视图或本地索引场景要额外验证结构对齐
即使基表分区合理,上层对象没对齐也会让裁剪失效:
- 物化视图没显式定义
PARTITION BY RANGE,哪怕基表按create_date分区,MV 仍是单段,查任何时间都全扫 - 本地索引本身不跨分区,但若查询没走裁剪,就会变成“每个分区都扫一遍索引 + 回表”,逻辑读暴增
- 检查 MV 定义是否包含分区键列,且 WHERE 条件直接引用该列(不能是
TRUNC(created_date))
真正卡住排查进度的,往往是绑定变量类型不一致或统计信息长期未更新——这两点在应用上线后容易被忽略,但影响是硬性的。别只盯着 SQL 写法,得进 DBA_TAB_PARTITIONS 和 PLAN_TABLE 里翻数据。


















