Oracle相同的一个SQL执行计划截然不同的解决方法

最近在项目中遇到了一个很奇怪的问题,有个结构稍微复杂点的SQL(left join了十几张表)在一个项目地A查询时两秒返回数据,但是相同的SQL部署在另外一个项目地B却花费90多秒,更奇怪的是项目地B的数据库服务器比A好很多,还有数据总行数也比项目地A的少一些,然而花费的时间却多了几十倍。这个时候我比较了一下两个项目地该条sql的执行计划,发现执行计划是截然不同的。

刚开始一直以为是SQL层面的问题,不断尝试优化对应的索引,经过优化后,项目地B还是需要花费40多秒,感觉SQL层面很难进行优化了,我已经尽力了,这时候就开始怀疑会不会是其他原因,如数据库安装问题,数据库配置信息pga、sga参数等。

最后,只能选择求助公司的DBA同事,经过DBA三个多小时的努力,终于找出问题所在:

对于执行计划中,在note部分如果有“cardinality feedback used for this statement”,表示使用了基数反馈(Cardinality Feedback)。基数反馈(Cardinality Feedback)是Oracle 11.2开始Oracle有了一种新的特性,Cardinality Feedback是一个优化器自动优化的过程,优化器会自动修正重复执行的查询的执行计划。对于一些复杂的查询,比如多字段条件,字符串范围比较,数据SKEW等等,以及缺乏统计信息,优化器可能不能够产生一个完全准确的基数估计, 如丢失或统计数据不准确,或复杂的谓词的基数估计。cardinality feedback 就是基于这一原因而产生的。_optimizer_use_feedback参数默认是TRUE,即开启Cardinality Feedback,FALSE为关闭Cardinality feedback。

解决方法:关闭oracle的一个参数,对于结构上不复杂的语句

alter system set "_optimizer_use_feedback"=false;

设置完后,重新执行SQL,一秒就查询出来了;接下来反复执行sql,发现执行时间恢复正常。

你可能感兴趣的:(数据库,Oracle,数据库)