1. 程式人生 > >處理Oracle EBS R12標準功能切換職責速度慢的問題

處理Oracle EBS R12標準功能切換職責速度慢的問題

最近使用者(用EBS系統的時候)普遍反饋一個問題:
切換職責的時候,很慢,基本要5秒左右。有時候甚至要等上7秒以上。
就是下圖,在點確定之後,切換到另外一個職責,經常要5秒左右。
這裡寫圖片描述

這個問題如何處理?

其實是這樣子的,如果以前使用系統的時候正常,現在突然變慢,在伺服器的效能沒大幅度下降的前提下,應該是某個SQL的執行計劃出現問題了。
所以,現在的處理這類“突然慢”的問題,核心的解決方法還是:找出是哪條SQL,慢在哪裡。這樣子才可以解決問題!

怎麼找出是哪條SQL慢呢?正常情況下,一般跟蹤會話的執行情況即可。例如開個10046事件跟蹤會話的執行SQL情況等等。
鑑於有些人不懂如何這種跟蹤的方式,這裡說的找出該會話執行慢的SQL的辦法是一個比較簡單的辦法。
看下面的步驟:

1 首先,開啟系統,在職責的介面,直接檢視幫助–>關於Oracle Application,找出該職責對應的會話ID(SID),然後執行下面的SQL。
這裡寫圖片描述
這裡寫圖片描述
可以看出這裡是4208:

SELECT A.INST_ID,A.SID,A.PROCESS,A.ACTION,A.STATUS,A.SQL_ID,A.SQL_CHILD_NUMBER
  FROM GV$SESSION A
 WHERE A.SID=4208
   AND A.INST_ID=1;

2 接著,回到EBS介面,做切換職責的動作,然後瞬速切回到開發工具查詢上面的SQL!確認STATUS=ACTIVE的時候,哪條SQL是停留時間最長的。
需要注意的是:要反覆操作多幾次,如果確實是切換職責的時候卡在某條SQL,那應該很容易可以看出來。然後記錄下對應的SQL_ID以及SQL_CHILD_NUMBER
這樣子,就基本可以定位解決問題的關鍵點:切換職責的時候,究竟跑哪條SQL特別的慢!

SELECT SQL_TEXT
      ,INST_ID
      ,SQL_ID
      ,CHILD_NUMBER
      ,ROUND(ELAPSED_TIME / 1000000 / DECODE(EXECUTIONS, 0, 1, EXECUTIONS),5) PER_ELAPSED_TIME--單條SQL的平均執行時間(秒)
  FROM GV$SQL
 WHERE SQL_ID='0y7y17bcappxk'
   AND CHILD_NUMBER=0
   AND INST_ID=1;

我這邊切換職責,卡的SQL是:

SELECT P.PID, P.SERIAL#, P.SPID FROM
V$PROCESS P, V$SESSION S WHERE S.AUDSID = USERENV('SESSIONID') AND S.PADDR = P.ADDR

3 找到是哪條SQL慢,問題就可以分析了:為什麼慢。
我最近處理這個問題,是因為SQL的執行計劃出現的問題!
速度慢的:

SQL_ID  0y7y17bcappxk, child number 0
-------------------------------------
SELECT P.PID, P.SERIAL#, P.SPID FROM V$PROCESS P, V$SESSION S WHERE 
S.AUDSID = USERENV('SESSIONID') AND S.PADDR = P.ADDR

Plan hash value: 1245246913

------------------------------------------------------------------------------------
| Id  | Operation                  | Name            | E-Rows |E-Bytes| Cost (%CPU)|
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                 |        |       |     1 (100)|
|   1 |  NESTED LOOPS              |                 |      1 |    60 |     0   (0)|
|   2 |   MERGE JOIN CARTESIAN     |                 |    149 |  5960 |     0   (0)|
|   3 |    NESTED LOOPS            |                 |      9 |   108 |     0   (0)|
|   4 |     FIXED TABLE FULL       | X$KSLWT         |    100 |   800 |     0   (0)|
|*  5 |     FIXED TABLE FIXED INDEX| X$KSLED (ind:2) |      1 |     4 |     0   (0)|
|   6 |    BUFFER SORT             |                 |     17 |   476 |     0   (0)|
|*  7 |     FIXED TABLE FULL       | X$KSUPR         |     17 |   476 |     0   (0)|
|*  8 |   FIXED TABLE FIXED INDEX  | X$KSUSE (ind:1) |      1 |    20 |     0   (0)|
------------------------------------------------------------------------------------

執行計劃正常的應該是:

SQL_ID  0y7y17bcappxk, child number 0
-------------------------------------
SELECT P.PID, P.SERIAL#, P.SPID FROM V$PROCESS P, V$SESSION S WHERE 
S.AUDSID = USERENV('SESSIONID') AND S.PADDR = P.ADDR

Plan hash value: 2285488774

-----------------------------------------------------------------------------------------------
| Id  | Operation                  | Name            | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                 |        |       |     3 (100)|          |
|   1 |  NESTED LOOPS              |                 |      2 |   120 |     3 (100)| 00:00:01 |
|*  2 |   HASH JOIN                |                 |      2 |   112 |     3 (100)| 00:00:01 |
|   3 |    NESTED LOOPS            |                 |      2 |    56 |     1 (100)| 00:00:01 |
|   4 |     FIXED TABLE FULL       | X$KSLWT         |   1154 |  9232 |     0   (0)|          |
|*  5 |     FIXED TABLE FIXED INDEX| X$KSUSE (ind:1) |      1 |    20 |     0   (0)|          |
|*  6 |    FIXED TABLE FULL        | X$KSUPR         |    686 | 19208 |     2 (100)| 00:00:01 |
|*  7 |   FIXED TABLE FIXED INDEX  | X$KSLED (ind:2) |      1 |     4 |     0   (0)|          |
-----------------------------------------------------------------------------------------------

由於執行計劃在Toad裡面直接執行,也是沒問題的。
所以,基本可以斷定切換職責慢的資料庫環境的執行計劃出現問題了。

select s.SQL_TEXT,'exec sys.dbms_shared_pool.purge('''||s.ADDRESS||','||s.HASH_VALUE||''',''c'');'
  from v$sqlarea s
 where sql_id = '0y7y17bcappxk';

exec sys.dbms_shared_pool.purge('0700000673865A50,3635074994','c');

將這個執行計劃Purge掉之後,Oracle再重新執行SQL的時候,會重新找執行計劃。
這邊重新找的執行計劃是正常的,所以,切換職責的速度也就正常了!實測基本是2秒左右就可以切換好職責。
問題得以解決!