3

特定のデータベース ユーザーに対して実行された SQL ステートメントをトレースしようとしています。AUDITING を有効にしておらず、Oracle 11g を使用しています。

次のクエリがあります。

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' を実行している複数のユーザーが同じ db ユーザーに接続されている場合、どの 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 に保存される期間は? オラクルはいつそれをビューから削除しますか?

よろしくお願いします。

プラディープ

4

3 に答える 3

6

追加の構成 (監査を有効にするなど) を行ったり、妥協したりしなければ、探しているデータを取得できない可能性があります。解決しようとしているビジネス上の問題は何ですか? 問題によっては、必要な情報を記録できるようにデータベースを構成するための最も簡単な方法を特定できる場合があります。

Oracle は、特定のユーザーが特定のクエリを実行した回数 (特に、特定のオペレーティング システム ユーザーが実行した回数ではない) をどこにも保存しようとしません。SQL_IDinは、セッションが現在実行中であることV$SESSIONのみを示します。SQL_ID私が推測しているように、これがクライアント/サーバー アプリケーションである場合、これは 99% の確率で NULL である可能性が非常に高く、ほとんどの場合、セッションは SQL を実行しておらず、ユーザーを待機しているためです。何かをする。PREV_SQL_IDinは、実行された前のV$SESSIONSQL ステートメントです。少なくとも一般的には ではありませんNULL。ただし、値は 1 つしかなく、そのセッションで実行された SQL ステートメントの履歴はありません。

V$SQLビューは、SQL 共有プールの内容を表しています。SQL ステートメントが共有プールから期限切れになると、V$SQLビューに表示されなくなります。それがどのくらいの速さで行われるかは、多くの要因に依存します。たとえば、誰かがステートメントを実行する頻度、新しいステートメントが解析される頻度 (通常、アプリケーションがバインド変数を正しく使用しているかどうかに大きく依存します)、共有プールの大きさなどです。一般に、それは数分からデータベースがシャットダウンするまでの間のどこかになります。

AWR テーブルを使用するライセンスがあり、完全に正しい答えよりも概算に関心がある場合は、AWR テーブルのいくつかを見ることで、必要な情報を取得できる可能性があります。例えば、V$ACTIVE_SESSION_HISTORY各セッションが毎秒アクティブに実行していた SQL ステートメントをキャプチャします。ただし、これはクライアント/サーバー アプリケーションであるため、ほとんどの場合、セッションは非アクティブになり、何もキャプチャされません。ただし、たまたまセッションでキャプチャされた SQL ステートメントから、さまざまな SQL ステートメントの相対的な頻度についてある程度のアイデアが得られます。もちろん、実行時間の長い SQL ステートメントは、特定の瞬間にアクティブになる可能性が高いため、同様にキャプチャされる可能性が高くなります。クエリ A と B の両方がまったく同じ時間で実行され、過去 1 時間に A を 5 回、B を 10 回実行するセッションがキャプチャされた場合、B は A の約 2 倍の頻度で実行されると結論付けることができます。クエリの平均実行時間、クエリがキャプチャされる平均確率は、クエリが実行される秒数になります (0.5 秒で実行されるクエリは 50% の確率でキャプチャされ、0.25 秒で実行されるクエリは 25% の確率でキャプチャされます)。これにより、特定のセッションが特定のクエリを実行した頻度を見積もることができます。これは、特に短い時間枠の場合や、実際の実行時間が変動しやすいクエリの場合、正確な数値とはかけ離れています。

表示されているデータV$ACTIVE_SESSION_HISTORYは、通常、数時間利用できます。次に、テーブルにサンプリングされ、DBA_HIST_ACTIVE_SESS_HISTORY利用可能なデータの量が桁違いに削減され、推定の精度が大幅に低下します。ただし、そのデータは、AWR の保持間隔が何であっても保持されます (デフォルトでは 1 週間ですが、多くのサイトでは 30 日または 60 日に延長されます)。

于 2012-07-10T15:01:47.660 に答える
1

オラクルのドキュメントによると

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 とハッシュ値

以下のSQLを変更してください

    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
于 2012-07-10T15:09:02.133 に答える
0

これを試して

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 を実行しているログにのみ関心があると思いますか?

于 2014-08-12T15:45:34.567 に答える