oracle 11g rac升级到19c后sql变慢,大概率是优化器因统计信息未重收集、直方图缺失或采样失真而误判数据分布;应优先比对执行计划是否从索引扫描变为全表扫描等突变,而非直接修改sql。
oracle 11g rac升级到19c后sql变慢,大概率不是sql写得有问题,而是优化器“看错”了数据分布——统计信息没重收集、直方图缺失、采样失真,这三类问题占实际性能衰退案例的80%以上。
查执行计划突变比查SQL本身更有效
别一上来就改SQL或加hint。先确认是不是执行路径变了:
- 在19c中对慢SQL执行
EXPLAIN PLAN FOR SELECT ...,再用SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)看实际走的路径 - 重点比对:是否从
INDEX RANGE SCAN变成TABLE ACCESS FULL,或从NESTED LOOPS变成HASH JOIN - 如果和11g里用
DBMS_XPLAN.DISPLAY_AWR查到的历史计划不一致,基本可锁定是统计信息或优化器行为变化导致
DBMS_STATS.GATHER_SCHEMA_STATS不能直接开跑
盲目执行会放大问题,尤其在分区表、LOB字段多、状态码字段集中的业务库中:
- 避免
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE:19c对超大表默认采样逻辑更激进,容易低估高频值密度,导致直方图不准 -
method_opt => 'FOR ALL COLUMNS SIZE AUTO'在19c中倾向少建直方图;对取值少但倾斜严重的字段(如order_status只有'P','S','C'),必须显式写成'FOR COLUMNS SIZE 254 order_status' -
cascade => TRUE必须配合degree => 4或更高:否则索引统计滞后于表统计,优化器看到“表小但索引大”,反而弃用索引
驱动和优化器兼容性开关要同步验证
有些SQL在PL/SQL Developer里快、应用里慢,本质是JDBC驱动或客户端行为不一致:
- 若用旧版JDBC(如ojdbc6),可能触发隐式类型转换或绑定变量窥探失效;优先升级到
ojdbc8或ojdbc11 - 临时验证可用
/*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.4') */强制回退优化器行为,但仅作诊断用,不可长期依赖 - 注意
sqlnet.ora中的SQLNET.ALLOWED_LOGON_VERSION_SERVER设置,若设为8以下,可能影响部分安全特性启用,间接干扰统计信息收集权限
最易被忽略的是:迁移后未清理11g遗留的动态采样(dynamic_sampling)Hint,或未禁用已废弃的隐式转换参数(如 _optimizer_ignore_hints=FALSE 默认值在19c中已不同)。这些细节不会报错,但会让统计信息和执行计划持续处于“半生效”状态。











