• ORACLE实际执行计划与预估执行计划不一致性能优化案例


     

    在一台ORACLE服务器上做巡检时,使用下面SQL找出DISK_READ最高的TOP SQL分析时,分析过程中,有一条SQL语句的一些反常现象,让人觉得很奇怪:

     

    SELECT SQL_ID,
           SQL_TEXT, 
           DISK_READS, 
           BUFFER_GETS, 
           PARSING_SCHEMA_NAME, 
           EXECUTIONS 
    FROM   V$SQLAREA 
    ORDER  BY DISK_READS DESC; 

     

    在SQL Developer中查看SQL的预估执行计划,发现执行计划走INDEX UNIQUE SCAN,而且IO COST其实不高。如下所示,而且执行次数也不是非常多,那么推断:很有可能这个SQL的实际执行计划跟预估的执行计划有很大偏差。

     

    SELECT 
     "Extent1"."SC_NO" AS "SC_NO", 
     "Extent1"."CUSTOMER_CD" AS "CUSTOMER_CD", 
     "Extent1"."FACTORY_CD" AS "FACTORY_CD", 
     "Extent1"."REQ_USER_ID" AS "REQ_USER_ID", 
     "Extent1"."REQ_USER_GRP_ID" AS "REQ_USER_GRP_ID"
     FROM "SC_HD" "Extent1"
     WHERE ("Extent1"."SC_NO" = :p__linq__0) AND (ROWNUM <= (1) )

     

     

     

    clip_image001[4]

     

     

    于是根据SQL_ID生成了对应SQL的awrsqrpt报表,如下截图所示,实际执行计划确实是全表扫描,Buffer Gets与Disk Reads也很高

     

     

    clip_image002[4]

     

     

    在sqltrpt.sql里面分析查看该SQL时,如下所示, 可以发现其绑定变量存在隐式转换(implicit data type conversion),导致执行计划走全表扫描

     

     

    clip_image003[4]

     

     

    于是分析了一下绑定变量的类型,发现:P__LINQ__0的类型为NVARCHAR(32) 而实际上字段SC_NO为VARCHAR(16),所以肯定是应用程序里面给该绑定变量赋值出现了问题。

     

    SQL> COL NAME FOR A32;
    SQL> COL DATATYPE_STRING FOR A20;
    SQL> COL VALUE_STRING FOR A20;
    SQL>  SELECT NAME, DATATYPE_STRING, VALUE_STRING
      2   FROM v$sql_bind_capture 
      3   WHERE SQL_ID='&SQL_ID' ;
    Enter value for sql_id: dhg6qnxv9c4nz
    old   3:  WHERE SQL_ID='&SQL_ID'
    new   3:  WHERE SQL_ID='dhg6qnxv9c4nz'
     
    NAME                             DATATYPE_STRING      VALUE_STRING
    -------------------------------- -------------------- --------------------
    :P__LINQ__0                      NARCHAR2(32)         GS17K16005
     
    SQL> 

     

    后面开发人员协助检查发现,因为这个SQL是代码中Lambda表达式自动生成,后面在Property中设置了字段类型以及长度,问题解决。

     

     

                //SC_HD

                modelBuilder.Entity<SC_HD>().ToTable("SC_HD", OracleSchema);

                modelBuilder.Entity<SC_HD>().HasKey(x => x.SC_NO);

     

     

    clip_image004[4]

  • 相关阅读:
    Eclipse 不能build, pom文件上面有叉叉 解决办法
    WCF分布式开发必备知识(1):MSMQ消息队列
    MSMQ创建消息队列出现“工作组安装计算机不支持该操作”
    在asp.net利用jquery.MultiFile实现多文件上传(转载)
    让ASP.NET MVC不使用jsonp也可以跨域访问
    设计模式学习之适配器模式(Adapter,结构型模式)(14)
    设计模式学习之策略模式(Strategy,行为型模式)(13)
    设计模式学习之命令模式(Command,行为型模式)(12)
    设计模式学习之代理模式(Proxy,结构型模式)(11)
    设计模式学习之组合模式(Composite,结构型模式)(10)
  • 原文地址:https://www.cnblogs.com/wangchaoyuana/p/7545428.html
Copyright © 2020-2023  润新知