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) )

 

 

 

 

 

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

 

 

 

 

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

 

 

 

 

于是分析了一下绑定变量的类型,发现: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);

 

 

时间: 2024-08-31 03:45:48

ORACLE实际执行计划与预估执行计划不一致性能优化案例的相关文章

《Oracle数据库性能优化方法论和最佳实践》——第2章 Oracle性能优化方法论的发展 2.1 基于局部命中率分析的优化方法论

第2章 Oracle性能优化方法论的发展 Oracle数据库在开发和使用过程中对数据库的性能优化极为重视,几乎在每个版本的更新中都会对可优化的数据库做出改善.不仅如此,Oracle数据库还会使用优化方法来指导性能优化,会不断推出新的性能优化方法论,并依据优化方法论持续完善其可观察的性能优化体系.从Oracle 6到现在的Oracle 12c,经历了Oracle 7.Oracle 8.Oracle 8i.Oracle 9i & R2.Oracle 10gR1 & R2.Oracle 11gR

从执行计划的预估行数看执行计划是否正确

  从执行计划的预估行数可以看出执行计划是否正确,作为优化的你曾经注意到了么?   今天在监控系统垃圾sql语句的时候发现一个sql语句跑了10个小时了,凭直觉这个sql肯定哪里出现问题了,好吧,老规矩,先看看内存中执行计划和具体的sql语句吧,这里的sql语句: INSERT /*+ append */ INTO CJG_MID_ACCT(ACCT,PARTY_NO,CHINESE_NAME,DATE_OPENED,RMB_CURRENT_BAL,BILL_DATE,RMB_CRLIM,AI_

Oracle AWR 阙值影响历史执行计划

      最近有网友提到为什么在dba_hist_sql_plan中无法查看到sql语句的历史执行计划,对于这个问题是由于缺省情况下,Oracle 设定的阙值并非捕获所有的sql语句,所以无法看到某些sql历史执行计划乃正常现象.在Oracle 9i的时候,我们可以通过设定不同的快照level获得不同程度的详细信息.也可以单独配置收集sql的阙值,如指定sql的执行次数,磁盘读的次数,解析调用的数量等.所有超出这个设置的sql语句都收集到snapshot之中.Oracle 10g,11g也有相

Oracle性能优化-读懂执行计划

Oracle的执行计划 得到执行计划的方式 Autotrace例子 使用Explain explain plan set STATEMENT_ID='testplan' for select * from dual; select lpad(' ',5*(level-1))||operation operation, options, object_name, cost,position from plan_table start with id=0 and STATEMENT_ID='test

Oracle执行计划filter下多个节点的优化

Oracle执行计划filter下多个节点的优化 FILTER操作是执行计划中常见的操作,这种操作有两种情况:   l 只有一个子节点,那么就是简单过滤操作. l 有多个子节点,那么就是类似NESTED LOOPS操作,只不过与NESTED LOOPS差别在于,FILTER内部会构建HASH表,对于重复匹配的,不会再次进行循环查找,而是利用已有结果,提高效率.但是一旦重复匹配的较少,循环次数多,那么,FILTER操作将是严重影响性能的操作,可能你的SQL几天都执行不完了. 真题1.执行计划里的a

【性能优化】执行计划与直方图

在Oracle中直方图是一种对数据分布质量情况进行描述的工具.它会按照某一列不同值出现数量多少,以及出现的频率高低来绘制数据的分布情况,以便能够指导优化器根据数据的分布做出正确的选择.在某些情况下,表的列中的数值分布将会影响优化器使用索引还是执行全表扫描的决策.当 where 子句的值具有不成比例数量的数值时,将出现这种情况,使得全表扫描比索引访问的成本更低.这种情况下如果where 子句的过滤谓词列之上上有一个合理的正确的直方图,将会对优化器做出正确的选择发挥巨大的作用,使得SQL语句执行成本

process-为什么在每分钟执行一次的任务计划中不能强制终止,要等待执行结束

问题描述 为什么在每分钟执行一次的任务计划中不能强制终止,要等待执行结束 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Diagnostics; //using System.Management; //using System.Management.Instrumentation; n

RDS SQL Server - 专题分享 - 巧用执行计划缓存之执行计划编译

背景引入 执行计划缓存是SQL Server内存管理中非常重要的特性,这篇文章是巧用执行计划缓存系列文章之五,探讨如何从执行计划缓存中获取查询语句执行计划编译的性能消耗,比如: 编译时间消耗 编译CPU消耗 编译内存消耗 缓存大小消耗 等等一系列非常有价值的统计信息. 什么是执行计划编译 SQL查询语句在提交到SQL Server主机服务之后,数据查询访问动作发生之前,SQL Server的编译器需要将查询语句进行编译,然后查询优化器生成最优执行计划.而这个编译和最优执行计划选择的过程,

如何让win7系统任务计划不弹窗执行

问题描述 如何让win7系统任务计划不弹窗执行 如何让win7系统任务计划不弹窗执行 win7操作系统中添加定时任务后执行bat脚本文件.每次执行bat脚本都会弹出框框taskeng.exe感觉很烦.如何执行这个bat脚本又不会弹出taskeng.exe框框.在后台默默执行就好了.不用弹出窗口.怎么设置啊 解决方案 在bat开头加上@echo off 解决方案二: 有个东东 叫 RunHiddenConsole, 百度一下, 不知道能满足你的要求么