本地索引是与分区表一一对应的索引,每个分区索引段仅覆盖本分区数据;报表场景常用因其支持分区裁剪,结合分区键过滤可大幅减少I/O。

什么是本地索引,为什么报表场景常用它
本地索引(Local Index)是与分区表一一对应的索引结构,每个分区的索引段只覆盖该分区的数据,不跨分区。在SQL报表场景中,尤其当查询常带分区键过滤(如按天/月查询销售数据),本地索引能天然实现分区裁剪——数据库只需访问目标分区的索引和数据块,大幅减少I/O和扫描范围。
设计本地索引的关键原则
不是所有字段都适合建本地索引。重点考虑以下三点:
-
必须包含分区键作为前导列:例如表按
report_date范围分区,本地索引应以report_date开头,否则无法保证分区对齐,可能退化为全局索引行为 -
紧贴高频查询条件组合:比如报表常查“某月某地区TOP10商品”,索引可设计为
(report_date, region_code, sales_amt),让排序+过滤一步到位 - 避免冗余和过宽:本地索引会为每个分区单独存储,列越多、数据越长,索引总大小呈倍数增长;一般不超过4列,优先选高选择性、小数据类型的列(如INT优于VARCHAR(200))
常见性能陷阱与应对方式
本地索引用不好反而拖慢报表:
-
全分区扫描无裁剪:查询没带分区键(如只查
WHERE product_id = 'P123'),数据库被迫扫描所有分区的本地索引,性能接近全表扫。解决办法是补上分区键,或为高频非分区键查询单独建全局唯一索引 -
索引列顺序错位:把低选择性列放前面(如
(status, report_date)),导致等值过滤后仍需大量回表。应把高过滤性列前置,分区键紧随其后 -
未定期维护:分区交换、删除后,本地索引状态可能变为
UNUSABLE,但外表看仍是VALID。需定期检查dba_indexes.status和dba_ind_partitions.status,必要时重建
验证与调优的小技巧
别只看执行计划里的“INDEX RANGE SCAN”,要确认是否真用了分区裁剪:
- 查
PLAN_TABLE中partition_start和partition_stop是否为具体数字(如KEY或数值),而非ALL - 用
DBMS_XPLAN.DISPLAY_CURSOR查真实IO:对比逻辑读(buffer_gets)在加分区键前后是否下降一个数量级 - 测试不同索引列序:用
/*+ INDEX(t idx_name) */强制走索引,观察一致性读和CPU时间变化,比单纯看响应时间更可靠










