ORACLE檢視SQL的執行次數/頻率

zlingyi發表於2015-06-17
ORACLE檢視SQL的執行次數/頻率


     在ORACLE資料庫應用調優中,一個SQL的執行次數/頻率也是常常需要關注的,因為某個SQL執行太頻繁,要麼是由於應用設計有缺陷,需要在業務邏輯上做出最佳化處理,要麼是業務特殊性所導致。如果執行頻繁的SQL,往往容易遭遇一些併發性的問題。
那麼如何檢視ORACLE資料庫某個SQL的執行頻率/次數呢? 有哪些途徑方法呢?
 
方法1: 透過查詢V$SQLAREA或V$SQL的EXECUTIONS來檢視SQL的執行次數,但是這個值的有效性需要結合FIRST_LOAD_TIME來判斷。因為V$SQLAREA或V$SQL中不儲存歷史資料,具有一定的時效性,所以如果要查詢很久以前的某個SQL執行次數是辦不到的。
關於V$SQLAREA
        FIRST_LOAD_TIME        VARCHAR2(19)       Timestamp of the parent creation time
        EXECUTIONS             NUMBER             Total number of executions, totalled over all the child cursors
 
如下所示,我們透過一個例子來演示如何查詢一個語句的執行次數。
SQL> COL  START_TIME FOR A20;
SQL> SELECT TO_CHAR(sysdate,'YYYY-MM-DD HH24:MI:SS') AS START_TIME FROM DUAL; 
START_TIME--------------------2014-11-20 13:51:21 
SQL> 
SQL> SELECT SQL_ID, SQL_TEXT,FIRST_LOAD_TIME, EXECUTIONS  
2  FROM V$SQLAREA  
3  WHERE SQL_TEXT LIKE '%SELECT * FROM TEST%'; 
SQL_ID                 SQL_TEXT                   RST_LOAD_TIME    EXECUTIONS----------- -------------------------------------- ---------------- ---------- 
SQL> SELECT * FROM TEST;          
ID NAME----------- ---------- 
SQL>
 SQL> SELECT SQL_ID, SQL_TEXT,FIRST_LOAD_TIME, EXECUTIONS  
2  FROM V$SQLAREA  
3  WHERE SQL_TEXT LIKE '%SELECT * FROM TEST%'; 
SQL_ID                SQL_TEXT                   FIRST_LOAD_TIME    EXECUTIONS----------- -------------------------------------- -4ntr8ag38ujwd   SELECT * FROM TEST             2014-11-20/13:51:40      1 
SQL> SELECT * FROM TEST;          ID NAME----------- ---------- 
SQL> 
SQL> SELECT SQL_ID, SQL_TEXT,FIRST_LOAD_TIME, EXECUTIONS  
2  FROM V$SQLAREA  
3  WHERE SQL_TEXT LIKE '%SELECT * FROM TEST%'; 
SQL_ID                SQL_TEXT                 FIRST_LOAD_TIME   EXECUTIONS------------- -------------------------------- --4ntr8ag38ujwd      SELECT * FROM TEST                2014-11-20/13:51:40      2
如果此時清空共享池,那麼你會發現V$SQLAREA中對應的SQL的EXECUTIONS次數清零了。
SQL> ALTER SYSTEM FLUSH SHARED_POOL; 
System altered 
SQL> SELECT * FROM TEST;          
ID NAME----------- ---------- 
SQL> 
SQL> SELECT SQL_ID, SQL_TEXT,FIRST_LOAD_TIME, EXECUTIONS  
2  FROM V$SQLAREA  
3  WHERE SQL_TEXT LIKE '%SELECT * FROM TEST%'; 
SQL_ID                SQL_TEXT                    FIRST_LOAD_TIME      EXECUTIONS------------- ----------------------------------- ----4ntr8ag38ujwd  SELECT * FROM TEST                2014-11-20/13:52:38     1 
如果要檢視某個時間段該SQL語句執行了多少次,那麼必須在這兩個時間段執行上面SQL語句,兩次EXECUTIONS的差值表示這段時間內SQL語句的執行次數。EXECUTIONS是全域性的,往往不能檢視某個會話或使用者執行了多少次。這也是其侷限性之一。
 
方法2:透過DBA_HIST_SQLSTAT關聯DBA_HIST_SNAPSHOT找出某些SQL的執行次數,但是部分快照如果沒有捕獲到有些SQL。這樣也就無法透過下面SQL語句檢視執行次數。也是就說這種方法是有缺陷的。執行越頻繁的語句,也越容易被SNAPSHOT抓取到.
SELECT M.SQL_ID ,       
       TO_CHAR(N.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD')   "DATETIME", 
       SUM(M.EXECUTIONS_DELTA)  EXECUTIONS
FROM    DBA_HIST_SQLSTAT M, DBA_HIST_SNAPSHOT N
WHERE     M.SNAP_ID  = N.SNAP_ID  AND M.DBID = N.DBID  AND M.INSTANCE_NUMBER = N.INSTANCE_NUMBER  AND M.INSTANCE_NUMBER=1  AND                 TO_CHAR(N.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD') ='2014-11-20'  AND M.SQL_ID=&SQL_ID
GROUP     BY M.SQL_ID , TO_CHAR(N.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD')
ORDER     BY M.SQL_ID


方法3:AWR報告檢視某個SQL的執行次數,同上面一樣,AWR報告也受SNAPSHOT影響。不一定捕獲了你需要查詢的SQL
 
檢視當前資料庫執行次數最多的SQL,例如,查詢執行最頻繁的TOP 15的SQL語句。
SELECT SQL_TEXT, EXECUTIONS  
FROM     (SELECT SQL_TEXT,               
        EXECUTIONS,               
        RANK() OVER(ORDER BY EXECUTIONS DESC) EXEC_RANK          
        FROM V$SQLAREA) 
WHERE EXEC_RANK <= 15;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28686045/viewspace-1702607/,如需轉載,請註明出處,否則將追究法律責任。

相關文章