由会话执行的Oracle查询

时间:2012-07-10 13:19:40

标签: sql oracle oracle11g

我正在尝试跟踪针对特定数据库用户执行的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中多长时间? Oracle何时从视图中删除它?

提前感谢你们,

与Pradeep

3 个答案:

答案 0 :(得分:6)

如果不进行更多配置(例如启用审核)或做出一些妥协,您可能无法获得您正在寻找的数据。您尝试解决的业务问题是什么?根据问题,我们可以帮助您确定配置数据库的最简单方法,以便能够记录您所追踪的信息。

Oracle不会尝试存储特定用户执行特定查询的次数(特别是特定操作系统用户的次数)。 SQL_ID中的V$SESSION仅表示会话当前正在执行的SQL_ID。如果,正如我猜测的那样,这是一个客户端 - 服务器应用程序,很可能99%的时间都是NULL,因为绝大多数时候,会话没有执行任何SQL,它正在等待用户做某事。 PREV_SQL_ID中的V$SESSION是先前执行的SQL语句 - 至少通常不是NULL。但它只有一个值,它不会有该会话执行的SQL语句的历史记录。

V$SQL视图表示SQL共享池中的内容。当SQL语句超出共享池时,它将不再位于V$SQL视图中。这种情况发生的速度取决于多种因素 - 某人执行语句的频率,解析新语句的频率(通常在很大程度上取决于您的应用程序是否正确使用绑定变量),共享池的大小等等通常情况下,这将在几分钟之间,直到数据库关闭。

如果您被许可使用AWR表并且您对近似值感兴趣而不是完全正确的答案,那么您可以通过查看某些AWR表来获取您所需的信息。例如,V$ACTIVE_SESSION_HISTORY将捕获每个会话每秒正在执行的SQL语句。但是,由于这是一个客户端 - 服务器应用程序,这意味着绝大多数情况下,会话将处于非活动状态,因此不会捕获任何内容。但是,碰巧会为会话捕获的SQL语句会让您对不同SQL语句的相对频率有所了解。当然,更长时间运行的SQL语句也更有可能被捕获,因为它们更有可能在给定的瞬间处于活动状态。如果查询A和B都执行完全相同的时间量并且会话被捕获执行A 5次并且B在过去一小时内执行10次,则可以得出结论B的执行大约是A的两倍。如果您知道查询的平均执行时间,捕获查询的平均概率将是查询执行的秒数(在0.5秒内执行的查询有50%的机会被捕获,一个在0.25执行秒有25%的可能性被捕获)因此您可以估计特定会话执行特定查询的频率。这与确切的数字相差甚远,特别是在较短的时间范围内,以及实际执行时间变化较大的查询。

V$ACTIVE_SESSION_HISTORY视图中的数据通常可以使用几个小时。然后将其抽样到DBA_HIST_ACTIVE_SESS_HISTORY表中,该表将可用数据量减少一个数量级,使得任何估计值都不太准确。但是,无论您的AWR保留间隔是多少,都会保留这些数据(默认情况下,这是一周,但许多站点将其增加到30或60天)。

答案 1 :(得分: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

请修改下面的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

答案 2 :(得分: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' s感兴趣?