2012-07-10 84 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的日志感兴趣?