• Oracle执行计划不稳定


      前段时间,在项目中碰到一个相当棘手的问题。我在写一张报表时需要查询客户数据库中已存在的视图(是早期开发就有的),相对应的销售表中已有上千万条数据,写完后台逻辑将对应数据查出来没任何问题。但是在界面上再点击查询按钮。问题就来了:页面直接卡死。

      排除掉其他常见问题,例如语句性能,索引,缓存等等。最后发现奇怪的现象,正常来讲同样的一条SQL查询语句,根据执行计划,第一次查询完以后,后续再执行相同的语句应该很快才对。可是,现实却是第一次查询不慢(优化后2秒内查询),第二次以后就挂掉。困扰了好久不知道问题所在,也向相关群里的大牛去咨询也得不到结果。(数据库为oracle11G,项目为.net EF开发模式。)

      最后求助团队老大,老大找来专业的DBA终于找出原因。

      其实,算是Oracle11G的一个BUG。。。

      11.2开始Oracle有了一种新的特性Cardinality Feedback,Cardinality Feedback是一个优化器自动优化的过程,优化器会自动修正重复执行的查询的执行计划。对于一些复杂的查询,比如多字段条件,字符串范围比较,数据SKEW等等,以及缺乏统计信息,优化器可能不能够产生一个完全准确的基数估计, 如丢失或统计数据不准确,或复杂的谓词的基数估计。cardinality feedback 就是基于这一原因而产生的。_optimizer_use_feedback参数默认是TRUE,即开启Cardinality Feedback,FALSE为关闭Cardinality feedback。由于在11GR2中Cardinality feedback生效存在很多限制且BUG较多,故没必要启用。

      上段话是同事知道了原因后整理出来了的。 也就是说要关闭oracle的一个参数,对于结构上不复杂的语句,其实是看不到什么影响的。

      alter system set "_optimizer_use_feedback"=false;

         可以以一下方式验证参数是否真正关闭。

    SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describe FROM SYS.x$ksppi x, SYS.x$ksppcv y
    WHERE x.inst_id = USERENV ('Instance') AND y.inst_id = USERENV ('Instance') AND
    x.indx = y.indx AND x.ksppinm LIKE '%optimizer_use_feedback%';

    结果:参数关闭后,同样的语句,多次执行,已经不再会挂掉,跟数据库上千万的数据没有多大关系,每次执行可以保证在两秒左右。至此问题总算能解决。

  • 相关阅读:
    restful接口设计规范总结
    SSM框架中,配置数据库连接的问题
    Java通过mysql-connector-java-8.0.11连接MySQL Server 8.0遇到的几个问题
    浅谈Spring的PropertyPlaceholderConfigurer
    过滤器与拦截器的区别
    SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系
    SpringMVC中使用Interceptor拦截器
    mybatis中模糊查询的使用以及一些细节问题的注意事项
    mybatis generator(MyBatis的逆向工程)
    mybatis-generator生成逆向工程两种方式
  • 原文地址:https://www.cnblogs.com/LinXuDong/p/6077302.html
Copyright © 2020-2023  润新知