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;
SQLSELECT 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]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM