Oracle 19C自动索引导致SQL性能下降

来源:这里教程网 时间:2026-03-03 21:54:23 作者:

场景描述

        某单位在将数据库从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.对高吞吐量表采用增量统计信息收集策略

相关推荐

热文推荐