2012-07-10 75 views
2

我正在嘗試跟蹤針對特定數據庫用戶執行的SQL語句。我沒有啓用AUDITING,我正在使用Oracle 11g。由會話執行的Oracle查詢

我有以下查詢:

SELECT 
    S.MODULE, 
    SQL_TEXT , 
    S.EXECUTIONS  
FROM 
    SYS.V_$SQL S, 
    SYS.ALL_USERS U 
WHERE 
    S.PARSING_USER_ID=U.USER_ID 
    AND UPPER(U.USERNAME) IN ('USERNAME') 
    AND (UPPER(s.MODULE)='APP.EXE') 
ORDER BY S.LAST_LOAD_TIME 

但如果運行「APP.EXE」多個用戶連接到同一個數據庫用戶,我無法理解這OS用戶執行該查詢。所以我嘗試加入V $ SESSION視圖來獲取用戶詳細信息。

SELECT 
    S.MODULE,SQL_TEXT ,SN.OSUSER, SN.MACHINE, S.EXECUTIONS 
FROM 
    SYS.V_$SQL S, 
    SYS.ALL_USERS U, 
    V$SESSION SN 
WHERE 
    S.PARSING_USER_ID=U.USER_ID 
    AND UPPER(U.USERNAME) IN ('USERNAME') 
    AND (UPPER(S.MODULE)='APP.EXE') 
    AND S.SQL_ID=SN.SQL_ID 
ORDER BY S.LAST_LOAD_TIME 

但這並不似乎是工作(在我的情況下,它沒有返回任何行) 所以,我有以下幾個問題

1)我如何查詢通過執行每場會議?

2)V_ $ SQL的EXECUTIONS列似乎來自所有會話的執行。如何知道會話執行特定查詢的次數?

3)有關查詢的記錄將存儲在V_ $ SQL中多久? Oracle何時從視圖中刪除它?

感謝你的所有提前,

普拉迪普

回答

5

你可能不會得到,你沒有做更多的配置(如啓用審覈)或作出一些妥協尋找數據。您試圖解決的業務問題是什麼?根據問題,我們可以幫助您確定配置數據庫的最簡單方法,以便記錄您之後的信息。

Oracle不會嘗試存儲特定用戶多少次(特別是不是特定操作系統用戶多少次)執行特定查詢的地方。 V$SESSION中的SQL_ID僅指示會話當前正在執行的SQL_ID。如果我猜測,這是一個客戶端 - 服務器應用程序,99%的時間很可能是NULL,因爲絕大多數時間,會話沒有執行任何SQL,它正在等待用戶做某事。 V$SESSION中的PREV_SQL_ID是先前執行的SQL語句 - 至少通常不會是NULL。但它只有一個值,它不會有該會話執行的SQL語句的歷史記錄。

V$SQL視圖表示SQL共享池中的內容。當SQL語句超出共享池時,它將不再位於V$SQL視圖中。發生的速度取決於多種因素 - 人們執行語句的頻率,分析新語句的頻率(通常很大程度上取決於應用程序是否正確使用綁定變量),共享池的大小等等。通常情況下,這將在幾分鐘到數據庫關閉之間。

如果您有權使用AWR表,並且您對近似值而非完全正確的答案感興趣,則可以通過查看某些AWR表獲得所需的信息。例如,V$ACTIVE_SESSION_HISTORY將捕獲每個會話每秒都在積極執行的SQL語句。但是,由於這是一個客戶端 - 服務器應用程序,這意味着絕大多數時候會話將處於非活動狀態,因此不會捕獲任何內容。然而,碰巧爲某個會話捕獲的SQL語句會讓您對不同SQL語句的相對頻率有所瞭解。當然,長時間運行的SQL語句更可能被捕獲,因爲它們更有可能在給定的時刻處於活動狀態。如果查詢A和B的執行時間完全相同,並且會話在最後一個小時內執行了5次和B 10次,則可以得出結論,B執行的次數大約是A的兩倍。如果您知道查詢的平均執行時間,查詢被捕獲的平均概率將是查詢執行的秒數(在0.5秒內執行的查詢有50%的機會被捕獲,一個以0.25秒有25%的機會被捕獲),因此您可以估計特定會話執行特定查詢的頻率。對於實際執行時間更加可變的查詢,這種情況遠遠不是確切的數字,尤其是在較短的時間範圍內。

V$ACTIVE_SESSION_HISTORY視圖中的數據通常可用幾個小時。然後將其抽樣到DBA_HIST_ACTIVE_SESS_HISTORY表格中,該表格將可用數據量削減了一個數量級,使得任何估計的準確度都大大降低。但是,無論您的AWR保留時間間隔是多少(默認情況下,這是一週,儘管許多網站會將其增加到30或60天)。

+0

請注意,'prev_sql_id'可能不會像我們所期望的那樣保存最後一個sql,而是看到插入到與該id相關聯的'SYS.AUD $'中。 – YoYo 2017-03-14 23:33:07

0

根據Oracle文檔

SQL_ADDRESS -Used with SQL_HASH_VALUE to identify the SQL statement that is currently being executed 

SQL_HASH_VALUE - Used with SQL_ADDRESS to identify the SQL statement that is currently being executed 

請找到下面的鏈接以供參考

SQL_ADDRESS and HASH VALUE

請修改下面

SELECT S.MODULE, SQL_TEXT, SN.OSUSER, SN.MACHINE, S.EXECUTIONS 
     FROM SYS.V_$SQL S, SYS.ALL_USERS U, V$SESSION SN 
    WHERE S.PARSING_USER_ID = U.USER_ID 
     AND UPPER(U.USERNAME) IN ('USERNAME') 
     AND (UPPER(S.MODULE) = 'APP.EXE') 
     AND SN.sql_hash_value = S.hash_value 
     AND SN.sql_address = S.address 
    ORDER BY S.LAST_LOAD_TIME 
+2

這不會改變結果。加入'hash_value'和'address'是引入'sql_id'之前加入這些表的舊方法。它仍然適用於舊方法,它不會改變結果。您至多還不會獲取會話正在執行的當前SQL語句。 – 2012-07-10 16:15:12

+0

感謝您的澄清 – psaraj12 2012-07-10 16:57:47

0

的SQL試試這個

SELECT l.Sql_Id FROM v $ session s JOIN v $ session_longops l ON l.sid = s.Sid​​ AND l.Serial#= s.Serial#AND l.Start_Time> = s.Logon_Time WHERE s.Audsid = Sys_Context('USERENV','SESSIONID')

我假設你只對運行sql的日誌感興趣?