程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> ORACLE SQL調優案例一則,oraclesql調優

ORACLE SQL調優案例一則,oraclesql調優

編輯:Oracle教程

ORACLE SQL調優案例一則,oraclesql調優


收到監控告警日志文件(Alert)的作業發出的告警郵件,表空間TEMPSCM2不能擴展臨時段,說明臨時表空間已經被用完了,TEMPSCM2表空間不夠用了

Dear All:
 
  The Instance SCM2' alert log occured the ora errors ,please see the detail blow and take action for it. many thanks!

------------------------------------------- The errors is blow ------------------------------------------------------


193 |  | ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMPSCM2 
198 |  | ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMPSCM2 
200 |  | ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMPSCM2 
205 |  | ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMPSCM2 

--------------------------------------------end of errors-----------------------------------------------------------


Oracle Alert Services

同事在分析處理時,定位到臨時表空間是被一個問題SQL語句給耗盡了。

SELECT B.TABLESPACE, B.SEGFILE#, B.SEGBLK#, B.BLOCKS, A.SID, A.SERIAL#, A.USERNAME, A.OSUSER, A.STATUS
FROM v$session A, v$tempseg_usage B, v$sqlarea C
WHERE A.saddr = B.session_addr
AND C.address= A.sql_address
AND C.hash_value = A.sql_hash_value
ORDER BY B.tablespace, B.blocks;

WORKLOAD REPOSITORY SQL Report顯示,單個該SQL的HASH GROUP BY操作就要耗用臨時表空間229M,他給的建議是不擴展TEMPSCM2表空間,而是去優化這個SQL語句,因為大部分時候,該數據庫的臨時表空間使用率是非常低。我也同意他的分析結果。

從該SQL語句的執行計劃,就能看出這個SQL語句有問題,例如SC_LOT、PO_HD全表掃描只是為了獲取一小部分數據。

SELECT 'CEG'             AS FTY_CD, 
       2015              AS PD_Year, 
       2                 AS PD_Month, 
       a.po_no, 
       SUM(a.total_qty)  AS Order_Qty, 
       SUM(c.total_qty)  GO_QTY, 
       b.buyer_po_del_date, 
       b.status, 
       c.sam_group_cd, 
       c.style_chn_desc, 
       Max(e.short_name) AS CUSTOMER 
FROM   sc_lot a, 
       po_hd b, 
       sc_hd c, 
       gen_customer e, 
       (SELECT ct_no AS Job_order_no 
        FROM   mars_upload_temp 
        WHERE  fty_cd = 'CEG' 
               AND pd_yr = 2015 
               AND pd_mth = 2 
               AND date_type = '20150529 10:00:23881698737881698737') d 
WHERE  Upper(a.po_no) = Upper(b.po_no) 
       AND b.sc_no = c.sc_no 
       AND Upper(a.po_no) = Upper(d.job_order_no) 
       AND c.customer_cd = e.customer_cd(+) 
GROUP  BY b.buyer_po_del_date, 
          b.status, 
          c.sam_group_cd, 
          c.style_chn_desc, 
          a.sc_no, 
          a.po_no

了解了該語句的業務邏輯並和開發人員溝通後,發現WHERE語句的條件Upper函數根本沒有必要,取消Upper函數後PO_HD、GEN_CUSTOMER表走索引掃描了

SELECT 'CEG'             AS FTY_CD, 
       2015              AS PD_Year, 
       2                 AS PD_Month, 
       a.po_no, 
       SUM(a.total_qty)  AS Order_Qty, 
       SUM(c.total_qty)  GO_QTY, 
       b.buyer_po_del_date, 
       b.status, 
       c.sam_group_cd, 
       c.style_chn_desc, 
       Max(e.short_name) AS CUSTOMER 
FROM   sc_lot a, 
       po_hd b, 
       sc_hd c, 
       gen_customer e, 
       (SELECT ct_no AS Job_order_no 
        FROM   mars_upload_temp 
        WHERE  fty_cd = 'CEG' 
               AND pd_yr = 2015 
               AND pd_mth = 2 
               AND date_type = '20150529 10:00:23881698737881698737') d 
WHERE  a.po_no= b.po_no
       AND b.sc_no = c.sc_no 
       AND a.po_no= d.job_order_no 
       AND c.customer_cd = e.customer_cd(+) 
GROUP  BY b.buyer_po_del_date, 
          b.status, 
          c.sam_group_cd, 
          c.style_chn_desc, 
          a.sc_no, 
          a.po_no

但是SC_LOT表還是走全表掃描,經過分析發現SC_LOT表的PO_NO列的區分度非常大,應該可以通過建立索引優化。如下所示,建立索引後,SC_LOT不走全表掃描了。

執行計劃的代價(Cost)也從7014降為了254. 優化的效果非常顯著(Cardinality變得非常大,是因為表MARS_UPLOAD_TEMP數據在我測試階段發生了變化)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved