本地索引性能差异取决于查询是否包含分区键:带分区键且匹配前缀顺序时前缀索引可分区裁剪,否则均需全索引扫描;验证需查PSTART/PSTOP及DBA_IND_PARTITIONS。

本地前缀索引和本地非前缀索引在查询性能上差异显著,关键不在于“哪种更快”,而在于“查询条件是否包含分区键”——不带分区键的查询,本地非前缀索引可能全索引扫描;带分区键且能匹配前缀顺序的,前缀索引才有分区裁剪优势。
为什么执行计划里看不到分区裁剪?
常见现象是 EXPLAIN PLAN 显示访问了所有本地索引分区,哪怕只查一个分区的数据。原因通常是:
- 查询
WHERE条件没包含表的分区键(如表按deal_date分区,但查询只写WHERE nbr = '123') - 本地非前缀索引(如
CREATE INDEX ix_local_no_nbr ON RANGE_PART_TAB(NBR) LOCAL)无法利用分区键做裁剪,Oracle 必须检查每个分区的NBR值 - 本地前缀索引(如
CREATE INDEX ix_local_yes_deal ON RANGE_PART_TAB(deal_date, nbr) LOCAL)只有在WHERE deal_date = ...或WHERE deal_date BETWEEN ...时才触发裁剪;若只写WHERE nbr = ...,同样全扫
怎么验证前缀索引是否真起了作用?
别只看 ROWS 估算值,重点查 DBA_IND_PARTITIONS 和执行计划中的 PSTART/PSTOP:
- 执行
SELECT index_name, partition_name, status FROM dba_ind_partitions WHERE index_name = 'IX_LOCAL_YES_DEAL',确认各分区状态正常 - 跑
EXPLAIN PLAN FOR SELECT * FROM RANGE_PART_TAB WHERE deal_date = DATE '2025-01-01'; - 查
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY) WHERE PLAN_TABLE_OUTPUT LIKE '%PSTART%',若PSTART = PSTOP = 3,说明只访问第 3 个索引分区;若显示PSTART = 1, PSTOP = 4(假设共 4 分区),就是全扫 - 对比非前缀索引:同一语句走
ix_local_no_nbr,PSTART/PSTOP几乎总是全范围,因为索引结构不绑定分区逻辑
建本地索引时,列顺序到底影响什么?
列顺序直接决定是不是前缀索引,也影响能否支持唯一约束:
-
CREATE INDEX i1 ON t(part_key, col_a) LOCAL→ 是前缀索引(part_key在第一位) -
CREATE INDEX i2 ON t(col_a, part_key) LOCAL→ 是非前缀索引(part_key不在第一位) - 只有前缀索引 +
UNIQUE才能用于表级唯一约束,例如:CREATE UNIQUE INDEX uq_local ON t(deal_date, id) LOCAL合法;但CREATE UNIQUE INDEX uq_bad ON t(id, deal_date) LOCAL会报错ORA-14039,因为无法保证跨分区唯一性 - 非前缀索引仍可加速单列查询(如只查
NBR),但代价是丧失分区裁剪能力,且维护开销略高(每个分区都要独立构建 B-tree)
真正容易被忽略的是:本地非前缀索引不是“不能用”,而是“用错场景就白建”。它适合高频按某非分区键点查、且该列选择性极高(比如主键)、同时表分区变动极少的场景;一旦要支持按日期范围批量查,前缀索引的裁剪收益远超想象——哪怕多存一列,也值得。



















