oracle查詢慢的原因


1.查看后台是否有鎖:

 

SELECT sq.INST_ID,

       SQ.SQL_TEXT, /*SQL文本*/

       SE.SID, /*會話的唯一標識,通常要對某個會話進行分析前,首先就需要獲得該會話的SID。*/

       SE.BLOCKING_SESSION,

       SQ.OPTIMIZER_COST AS COST_, /* COST 值*/

       SE.LAST_CALL_ET CONTINUE_TIME, /*執行時間*/

       SE.EVENT, /*等待事件*/

       SE.LOCKWAIT, /*是否等待LOCK(SE,P)*/

       SE.MACHINE, /*客戶端的機器名。(WORKGROUP\PC-201211082055)*/

       SQ.SQL_ID, /*SQL_ID*/

       SE.USERNAME, /*創建該會話的用戶名*/

       SE.LOGON_TIME, /*登陸時間*/

       'ALTER SYSTEM KILL SESSION ''' || SE.SID || ',' || SE.SERIAL# ||

       ''';' KILL --若存在鎖情況,會用到KILL鎖釋放~

  FROM gV$SESSION SE, /*會話信息。每一個連接到ORACLE數據庫的會話都能在該視圖中對應一條記錄,根據該視圖中的信息可以查詢該會話使用的用戶,正在執行或者剛剛執行的SQL語句*/

       /**/

       gV$SQLAREA SQ /*跟蹤所有SHARED POOL中的共享CURSOR信息,包括 執行次數,邏輯讀,物理讀等*/

WHERE SE.SQL_HASH_VALUE = SQ.HASH_VALUE

   AND SE.STATUS = 'ACTIVE'

   AND SE.SQL_ID = SQ.SQL_ID

   AND SE.USERNAME = SQ.PARSING_SCHEMA_NAME

      --過濾條件

   AND SE.USERNAME = 'FWSB' --用戶名

   and se.BLOCKING_SESSION is not null;

 

 

 

以下將重點的幾個列說明一下

SQL_TEXT——被鎖的語句;開發人員需要判斷,這里面有沒有反饋慢的功能對應的語句。

SID——被鎖的語句對應的SID;

BLOCKING_SESSION——鎖源頭,如圖所示,SID=510的語句導致SID=697的語句鎖了;

CONTINUE_TIME——被鎖的時間,單位為秒;

EVENT——被鎖語句的等待事件,比如read by other session,gc buffer busy acquire, enq:TX – row lock contention這些,

特別強調,如果看到enq:TX – row lock contention,這個是我們平時所說的鎖表,不同進程操作同一條數據。

MACHINE——被鎖語句的機器名,我們系統功能對應的應該為feng 或者 tiao,否則不是我們系統的語句;

SQL_ID——被鎖語句的SQL_ID;

 

如果慢的功能恰好在這里面被查出了,那么說明這個功能被鎖了。

這時候可以考慮把導致功能被鎖的語句發出來,讓其他開發人員確認一下對應功能。然后跟客戶或者運維同事反饋一下。

 

但是如果慢的功能沒有在這里面查出來,那需要按照接下來的流程處理了,有點繁瑣,但目前我這邊還沒有什么更好的方法。如果大家有,可以拿出來交流分享一下。

 

2.定位功能對應的語句

 

 

首先打開PLSQL,調出SESSION窗口,選擇上面的選擇框為ACTIVE SESSIONS 即正在執行中的進程。

然后查一下,當前執行的SESSION中,是否有慢的功能對應的語句,在“SQL文本”那個頁簽里面查找,

如果覺得這個頁簽展示的信息不足以幫助確定功能,可以選擇切換到“鎖”的頁簽,看到里面有OBJECT_NAME列,里面有功能涉及到的表名。C_TIME列有這個功能執行了多少秒,大體可以推測出功能是什么時間點觸發的。通過表名、時間,大概能判斷出是什么功能。如果通過這些還找不到,那可能需要找找別的原因了。如果一個開發人員表示自己也不清楚功能涉及到什么表,那我表示我已經無能為力了……

通過上面截圖的語句大概可以看出,這個進程跑的應該是全國業務,因為涉及到交互訂單項表和賬單表。但是具體業務功能,那需要全國模塊相關開發人員通過進程對應的語句具體分析了。(我這里只是隨便找了個語句舉例說明。)

 

 

 

有的時候,我們通過這種方式找到了慢的語句,但是粘貼出來發現有的地方是用‘冒號+數字’的形式展示的,這表示該處的參數使用了綁定變量。

 

 

此時,找到語句對應的SQL_ID,如圖所示,通過以下腳本查詢對應的綁定變量是多少

 

SELECT SQL_ID, NAME, DATATYPE_STRING, LAST_CAPTURED, VALUE_STRING

  FROM GV$SQL_BIND_CAPTURE

WHERE SQL_ID = '00fb2hc1psmrb'

ORDER BY LAST_CAPTURED DESC, POSITION;

 

--在出問題的實例上執行,請自行替換SQL_ID,此時該SQL還在SHARED POOL中,沒有被AGED OUT

 

SELECT INSTANCE_NUMBER,

       SQL_ID,

       NAME,

       DATATYPE_STRING,

       LAST_CAPTURED,

       VALUE_STRING

  FROM DBA_HIST_SQLBIND

WHERE SQL_ID = '00fb2hc1psmrb'

ORDER BY LAST_CAPTURED DESC, POSITION;

 

--請自行替換SQL_ID,此時是從AWR中查詢。

 

 

將語句中的B1 B2分別替換結果中的,B1 B2;

需要注意的是,一定要對應要參數后面的時間與語句執行的時間是否相同,如果不同說明當時語句執行時,並不是使用該組參數。

如果第一個語句查不到結果,那么可以嘗試一下第二個語句。

因為數據庫存儲的記錄數量有限,如果這種兩個都無法找到你想找的對應時間點的參數,那就只能放棄了。

 

最后總結一下處理流程:

1.      先查是否被鎖;

2.      如果被鎖,則找源頭開發人員確認;如果沒有被鎖,查后台是否有功能對應的進程;

3.      如果查到進程,確定一下慢的語句,如果條件允許,可以評估一下數據量;如果查不到進程,需要確認一下是否為其他原因,比如彈窗攔截,跑完沒有提示等等。


免責聲明!

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



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