导读:本期聚焦于阿里山老登创作的《Oracle 19c的Partial Indexing部分索引是什么?如何使用它优化大表索引空间?》,敬请观看详情。一张几亿行的大表,大部分查询只集中在最近几个月的数据上,却要为整张表维护一个庞大的索引,这是很多DBA都遇到过的困扰。Oracle 19c引入的Partial Indexing部分索引特性,允许对分区表的部分分区建立索引、部分分区不建索引,从根本上解决了这类场景下的空间浪费和维护开销问题。本文将详细讲解部分索引的工作原理、在分区表上的创建语法、与全表索引的性能对比,以及切换维护模式时的注意事项,帮助你判断自己的业务是否适合采用这项新特性。

在传统的关系型数据库设计里,索引要么建在整张表上,要么不建,没有中间状态。对于一张按时间分区的海量数据表来说,这往往意味着两难的处境:历史分区的数据很少被访问,但为了几个活跃分区的查询性能,不得不给所有分区都建上索引,白白消耗大量存储空间,还拖慢了数据加载速度。Oracle 19c引入的Partial Indexing(部分索引)特性正是针对这个痛点,它允许同一个分区表上的索引只覆盖部分分区,被排除的分区上不持有任何索引结构。本文将从原理、语法、使用场景和维护操作几个方面,详细介绍这个特性的实际使用方法。

Oracle 19c的Partial Indexing部分索引是什么?如何使用它优化大表索引空间?

一、Partial Indexing的基本原理

部分索引的核心机制与分区表的索引类别绑定在一起。Oracle的分区索引分为本地索引(local index)和全局索引(global index),而Partial Indexing只能作用于本地索引。它通过在索引级别指定INDEXING FULLINDEXING PARTIAL两种属性,配合每个分区自身的INDEXING ONINDEXING OFF属性,共同决定索引最终覆盖哪些分区。

具体规则是这样的:当索引被定义为INDEXING PARTIAL时,Oracle会检查表上每个分区的INDEXING属性,只有标记为INDEXING ON的分区才会真正出现在索引结构中,标记为INDEXING OFF的分区则完全不占用索引空间。查询优化器在生成执行计划时也清楚这一规则,对于访问被排除分区的查询,它不会尝试使用这个部分索引,从而保证查询结果的正确性。这一点和不可见索引不同,不可见索引只是优化器看不见,但结构仍在维护;部分索引则是物理上就不存在,DML操作时自然也不需要维护它。

需要注意的是,如果一个索引定义为INDEXING FULL(默认值),那么无论分区怎么设置INDEXING属性,所有分区都会被索引覆盖。换句话说,分区的INDEXING属性只有在部分索引下才有意义,两者是配合使用的关系。

二、创建部分索引的完整语法示例

创建部分索引分两步:先在表或分区级别设置INDEXING属性,再创建索引时指定INDEXING PARTIAL。下面通过一个订单表的实际例子演示完整过程。

-- 创建分区表,历史分区关闭索引,近三个月分区开启索引
CREATE TABLE t_orders (
    order_id      NUMBER,
    order_date    DATE,
    customer_id   NUMBER,
    amount        NUMBER
)
PARTITION BY RANGE (order_date)
(
    PARTITION p_202301 VALUES LESS THAN (DATE '2024-01-01') INDEXING OFF,
    PARTITION p_202401 VALUES LESS THAN (DATE '2024-02-01') INDEXING OFF,
    PARTITION p_202402 VALUES LESS THAN (DATE '2024-03-01') INDEXING ON,
    PARTITION p_202403 VALUES LESS THAN (DATE '2024-04-01') INDEXING ON,
    PARTITION p_max    VALUES LESS THAN (MAXVALUE)         INDEXING ON
);

-- 创建部分索引,只覆盖INDEXING ON的分区
CREATE INDEX idx_orders_cust ON t_orders (customer_id)
    INDEXING PARTIAL
    TABLESPACE idx_ts;

-- 验证索引状态
SELECT index_name, indexing, partitioned
FROM   user_indexes
WHERE  table_name = 'T_ORDERS';

如果表已经存在,也可以事后修改分区的索引属性。比如数据归档后想把某个分区排除出索引,使用ALTER TABLE ... MODIFY PARTITION语句即可,此时该分区上的索引段会被删除,空间立即释放。反向操作同理,把某个分区改成INDEXING ON后,需要在对应分区上重建部分索引,Oracle才会为新纳入的分区补建索引结构。

-- 将旧分区排除出部分索引,释放其索引空间
ALTER TABLE t_orders MODIFY PARTITION p_202401 INDEXING OFF;

-- 将归档后重新需要查询的分区纳入部分索引,需重建
ALTER TABLE t_orders MODIFY PARTITION p_202402 INDEXING ON;
ALTER INDEX idx_orders_cust REBUILD PARTITION p_202402;

还有一种常见做法是在表级别设置默认属性,新建分区自动继承。比如ALTER TABLE t_orders SET INDEXING ON之后,后续自动分区拆分产生的新分区默认都会带上INDEXING ON属性,避免遗漏。

三、适用场景与性能收益分析

部分索引最适合的场景是典型的冷热数据分离业务。以日志表、订单表为例,查询请求绝大多数集中在最近三到六个月的数据上,历史分区一年也访问不了几次。在这种分布下,使用部分索引可以把索引存储压缩到原来的百分之十几,同时大幅减少批量加载和删除历史数据时的索引维护开销,因为被排除的分区在写入时完全不需要更新索引。

从查询性能角度看,只要SQL的谓词条件能够被分区裁剪(partition pruning)限定在带索引的分区范围内,优化器就会正常使用部分索引,执行计划和普通本地索引没有区别。但如果查询范围跨过了冷热边界,比如统计全年数据,优化器会放弃部分索引改走全表扫描或分区全扫。因此在使用前一定要梳理清楚业务的查询模式,确认高频查询都落在热数据区间内。

另一个需要注意的点是执行计划的解读。通过DBMS_XPLAN查看部分索引相关计划时,操作名称会显示为PARTITION RANGE结合索引访问的组合,同时在INDEX提示后面能看到分区裁剪信息。监控方面,数据字典视图USER_IND_PARTITIONS中的STATUS列会显示USABLEUNUSABLE,被排除的分区在该视图中不产生记录,可以用这一点来核对索引覆盖情况。

-- 查看部分索引实际覆盖的分区
SELECT partition_name, status
FROM   user_ind_partitions
WHERE  index_name = 'IDX_ORDERS_CUST';

-- 对比空间占用:部分索引 vs 全表索引
SELECT segment_name, SUM(bytes)/1024/1024 AS size_mb
FROM   user_segments
WHERE  segment_name LIKE 'IDX_ORDERS%'
GROUP  BY segment_name;

四、使用限制与维护注意事项

部分索引虽然好用,但限制条件要记牢。首先它只支持本地分区索引,全局索引上无法使用INDEXING PARTIAL子句。其次,分区的INDEXING属性一旦设置,主键约束、唯一约束使用的索引同样会受到影响,如果唯一性约束依赖的列包含在分区键中则没有问题,否则需要谨慎评估。位图索引同样支持部分索引属性,但组合使用时要注意数据仓库场景下的并发限制。

维护层面的一个关键操作是切换分区时的行为。当使用EXCHANGE PARTITION和数据泵导入导出时,部分索引的属性会随分区元数据一起处理,交换进来的分区如果INDEXING属性不匹配,索引可能变为UNUSABLE状态,需要手动重建。另外,使用GoldenGate或Data Guard的逻辑复制环境时,建议在目标端提前确认部分索引的定义策略,避免主备两端索引覆盖范围不一致带来的性能差异。

最后给出一个实用的选型建议:如果你的表数据量在千万级以上、按时间或其他低频访问维度分区、且查询明显集中在部分分区,那么Partial Indexing基本都值得尝试。可以先在测试环境用真实数据建立对比索引,通过DBMS_XPLAN和段空间统计验证收益,再推广到生产环境。对于小表或者查询模式均匀分布在全表的业务,普通全表索引依然是更简单直接的选择。

Oracle 19cPartial Indexing部分索引修改时间:2026-09-08 00:30:36

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260908/52520.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。