在Oracle数据库的日常运维中,索引统计信息是CBO优化器生成合理执行计划的核心依据,如果统计信息过时或者缺失,很容易导致SQL走错执行计划,出现查询缓慢的问题。下面我们详细介绍收集索引统计信息的相关内容。

为什么需要收集索引统计信息
索引统计信息包含了索引的层级、叶子块数量、不同键值数量、聚簇因子等关键数据,CBO优化器会根据这些信息判断使用索引的成本,从而决定是否选择该索引来执行查询。当出现以下情况时,就需要及时收集索引统计信息:
- 新创建索引之后,没有自动生成统计信息
- 索引对应的表数据发生大量变更,比如批量插入、删除、更新超过一定比例
- 发现SQL执行计划异常,排查后发现索引统计信息过时
- 数据库迁移或者升级之后,需要重新确认统计信息准确性
常用收集方法:DBMS_STATS包
Oracle官方推荐使用DBMS_STATS包来收集统计信息,这个包功能全面,支持多种参数配置,能够灵活适配不同的收集需求。以下是几个常用的收集索引统计信息的存储过程。
1. 收集单个索引的统计信息
如果只需要收集某一个特定索引的统计信息,可以使用GATHER_INDEX_STATS过程,语法如下:
-- 收集指定索引的统计信息,需要指定索引所在的模式名和索引名
BEGIN
DBMS_STATS.GATHER_INDEX_STATS(
OWNNAME => 'SCOTT', -- 索引所属的模式名,大写
INDNAME => 'IDX_EMP_DEPTNO', -- 要收集的索引名称,大写
ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE, -- 自动采样比例,等价于100%采样
METHOD_OPT => 'FOR ALL COLUMNS SIZE AUTO', -- 自动收集列的统计信息,包括直方图
CASCADE => TRUE, -- 同时收集索引对应的表统计信息
FORCE => TRUE -- 即使索引被锁定也强制收集
);
END;
/2. 收集模式下所有索引的统计信息
如果需要批量收集某个模式下所有索引的统计信息,可以使用GATHER_SCHEMA_STATS过程,通过参数限定只收集索引相关统计信息:
-- 收集SCOTT模式下所有索引的统计信息
BEGIN
DBMS_STATS.GATHER_SCHEMA_STATS(
OWNNAME => 'SCOTT',
OPTIONS => 'GATHER INDEX', -- 仅收集索引统计信息,不收集表统计信息
ESTIMATE_PERCENT => 30, -- 采样30%的数据,适合大表场景提升收集效率
METHOD_OPT => 'FOR ALL INDEXED COLUMNS SIZE AUTO',
DEGREE => 4 -- 开启4个并行度,加快收集速度
);
END;
/3. 收集表及其所有索引的统计信息
如果表数据变更后,需要同时更新表和对应索引的统计信息,可以使用GATHER_TABLE_STATS过程,设置CASCADE参数为TRUE即可:
-- 收集EMP表及其所有索引的统计信息
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
OWNNAME => 'SCOTT',
TABNAME => 'EMP',
CASCADE => TRUE, -- 级联收集该表所有索引的统计信息
ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE,
METHOD_OPT => 'FOR ALL COLUMNS SIZE AUTO'
);
END;
/收集参数说明
为了让收集操作更符合实际场景,我们需要理解几个常用参数的作用:
| 参数名 | 作用说明 |
|---|---|
| ESTIMATE_PERCENT | 采样比例,设置为DBMS_STATS.AUTO_SAMPLE_SIZE时会自动选择最优采样比例,平衡准确性和收集效率 |
| METHOD_OPT | 控制列统计信息和直方图的收集方式,FOR ALL INDEXED COLUMNS表示仅收集索引列的统计信息 |
| DEGREE | 并行度,设置大于1的值可以并行收集,适合大表大索引场景,提升收集速度 |
| CASCADE | 设置为TRUE时,收集表统计信息的同时会级联收集该表所有索引的统计信息 |
| FORCE | 设置为TRUE时,即使索引被锁定或者统计信息被锁定,也会强制重新收集 |
注意事项
在收集索引统计信息时,还需要注意以下几点:
- 收集统计信息会产生一定的系统开销,建议放在业务低峰期执行,避免影响正常业务
- 对于极少变更的 historical 表,不需要频繁收集统计信息,可以设置统计信息锁定,避免误操作更新
- 如果索引是函数索引,收集统计信息时需要注意METHOD_OPT参数是否支持函数表达式的统计信息收集
- 收集完成后,可以通过
USER_IND_STATISTICS数据字典视图查看索引统计信息是否更新成功
查看索引统计信息的示例代码如下:
-- 查看SCOTT模式下索引IDX_EMP_DEPTNO的统计信息 SELECT INDEX_NAME, -- 索引名 LEAF_BLOCKS, -- 叶子块数量 DISTINCT_KEYS, -- 不同键值数量 AVG_LEAF_BLOCKS_PER_KEY, -- 每个键值平均占用的叶子块数 CLUSTERING_FACTOR -- 聚簇因子,反映索引和表数据的有序程度 FROM USER_IND_STATISTICS WHERE INDEX_NAME = 'IDX_EMP_DEPTNO';
注意:如果执行收集操作时提示权限不足,需要确认当前用户拥有EXECUTE权限 on DBMS_STATS,或者被授予了DBA权限。
Oracle索引统计信息DBMS_STATSCBO优化器统计信息收集修改时间:2026-05-25 23:35:09