场景描述
某单位在将数据库从Oracle 12C升级到19C后,核心报表查询性能显著下降。该查询原本在秒级完成,升级后执行时间延长至数分钟,导致业务阻塞。
问题排查步骤
1.确认自动索引状态 检查自动索引配置:
SELECT * FROM DBA_AUTO_INDEX_CONFIG;
发现
AUTO_INDEX_MODE
为
IMPLEMENT
,表示自动索引已启用并自动应用。
2.分析执行计划变化
通过AWR报告对比升级前后的SQL执行计划,发现原全表扫描(TABLE ACCESS FULL)变为索引范围扫描(INDEX RANGE SCAN),但效率反而降低。进一步检查发现新索引
SYS_AI_xxxx被创建在
report_table的
status字段上。
3.检查自动索引报告 生成自动索引活动报告:
SELECT DBMS_AUTO_INDEX.REPORT_ACTIVITY( activity_start => SYSTIMESTAMP - INTERVAL '7' DAY, activity_end => SYSTIMESTAMP ) AS report FROM DUAL;
报告显示自动索引
SYS_AI_xxxx
被标记为“VALID”,但实际该字段的区分度极低(仅3种状态值),导致索引选择性差。
4.验证索引有效性
手动执行问题SQL并强制使用新索引:
SELECT /*+ INDEX(report_table SYS_AI_xxxx) */ COUNT(*) FROM report_table WHERE status = 'PENDING';
执行时间仍较长,说明索引效率低下。
根本原因
自动索引功能误判低频更新的
status字段为高选择性字段,创建了低效索引,导致优化器选择了低效的执行计划。
解决方案
立即禁用自动索引(紧急恢复)
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','OFF');
删除无效自动索引
DROP INDEX SYS_AI_xxxx;
优化自动索引配置(长期方案) 排除特定表参与自动索引:
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'PROD_USER', NULL);
或限制自动索引仅分析不实施:
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','REPORT ONLY');
绑定原有执行计划 使用SPM固定原有高效计划:
-- 从AWR加载历史计划 DECLARE v_plan PLS_INTEGER; BEGIN v_plan := DBMS_SPM.LOAD_PLANS_FROM_AWR( begin_snap => 1500, end_snap => 1501, basic_filter => 'sql_id = ''abc123xyz456'''); END; /
优化统计信息收集策略 对高频DML表启用实时统计信息增强:
EXEC DBMS_STATS.SET_TABLE_PREFS('PROD_USER','REPORT_TABLE','INCREMENTAL','TRUE');
验证结果
问题SQL执行计划恢复为全表扫描,执行时间恢复至1.2秒。
自动索引模式调整为
REPORT ONLY后,每日自动生成索引建议报告供DBA人工审核。
核心表被排除在自动索引范围外,避免类似问题复发。
经验总结
Oracle 19C的自动索引功能(Auto Indexing)虽能优化部分场景,但需结合业务数据特征谨慎使用。建议:
1.新特性在生产环境启用前需充分测试
2.结合
DBMS_AUTO_INDEX.CONFIGURE精细控制适用范围
3.定期审查自动索引报告,配合SPM管理关键SQL执行计划
4.对高吞吐量表采用增量统计信息收集策略
