如何在 Oracle 12c 中跟踪 sql 查询?

Posted

技术标签:

【中文标题】如何在 Oracle 12c 中跟踪 sql 查询?【英文标题】:How do you track sql queries in Oracle 12c? 【发布时间】:2016-04-07 19:40:26 【问题描述】:

我们正在升级到 Oracle 12c,我需要跟踪应用程序正在执行的查询。换句话说,如果应用程序执行诸如 select 'foobar' from dual 之类的查询;我想在输出文件中看到文本“select 'foobar' from dual”。

如果我按照此处的说明进行操作:https://docs.oracle.com/database/121/TGSQL/tgsql_trace.htm#TGSQL809 我会得到包含如下统计信息但不包含实际 sql 查询的文件。

WAIT #0: nam='rdbms ipc message' ela= 2999770 timeout=300 p2=0 p3=0 obj#=-1 tim=1103506389
WAIT #0: nam='rdbms ipc message' ela= 9854 timeout=1 p2=0 p3=0 obj#=-1 tim=1103522400

*** 2016-04-07 15:07:20.715
WAIT #0: nam='rdbms ipc message' ela= 2999585 timeout=300 p2=0 p3=0 obj#=-1 tim=1106522506
WAIT #0: nam='rdbms ipc message' ela= 9690 timeout=1 p2=0 p3=0 obj#=-1 tim=1106532500

如果我查找这样的查询,我会得到 0 个结果: grep -rnw "foobar" --include=*.trc ./

【问题讨论】:

我不确定我是否理解您的问题...例如您是否在关注这些查询的执行频率、从应用程序执行的查询、等待时间、运行时间、执行计划等等……但是,取决于您所追求的,你或许可以从以下视图中得到你需要的东西:v$active_session_history、v$sql和v$sql_plan 这里的用例是:我想查看向数据库发出的每一个查询。 那么你当然可以从 select * from v$active_session_history ash, v$sql sql where sql.sql_id = ash.sql_id order by sample_time desc 中得到该信息;请注意,ASH 仅将信息保留几个小时,但如果您需要更好的保留,您可以定期将查询转储到历史表中。 【参考方案1】:

一个选项是为它查找 AWR 存储库。它将保留几天的 SQL。系统视图中有大量附加信息,所以这只是文本,但请随意探索。

SELECT DISTINCT u.username, to_char(substr(h.sql_text, 1, 4000)) sqltxt
  FROM dba_hist_sqltext h
  JOIN dba_hist_active_sess_history a ON a.sql_id = h.sql_id
  JOIN dba_users u ON u.user_id = a.user_id
 WHERE username = 'SYS';

我只是作为示例过滤了 SYS 的结果,但您可以随意更改它。

【讨论】:

【参考方案2】:

如果您想查看所有活动,最好为您设置一个 EM(企业管理器)。

如果你不这样做,gv$activity_session_history 将是一个很好的调用,使用分组函数时会更好看。根据您的应用程序正在推送的调用数量,简单地选择它会很混乱。

另一种方式,你可以以一般的方式看到它:

`
select s.parsing_schema_name,
             inst_id,
             sql_id,
             plan_hash_value,
             child_number,
             round(nullif(s.ELAPSED_TIME, 0) / nullif(s.EXECUTIONS, 0) / 1000000, 4) elap_per_exec,
       round(s.USER_IO_WAIT_TIME / nullif(s.ELAPSED_TIME, 0) * 100, 2) io_wait_pct,
       round(s.CLUSTER_WAIT_TIME / nullif(s.ELAPSED_TIME, 0) * 100, 2) cluster_wait_pct,
       round(s.application_wait_time / nullif(s.ELAPSED_TIME, 0) * 100, 2) app_wait_pct,
       round(s.CPU_TIME / nullif(s.ELAPSED_TIME, 0) * 100, 2) cpu_time_pct,
       round(s.PHYSICAL_READ_BYTES / nullif(s.EXECUTIONS, 0) / 1024 / 1024, 2) pio_per_exec_mb,
       round(s.PHYSICAL_READ_BYTES / nullif(s.PHYSICAL_READ_REQUESTS, 0), 2) / 1024 read_per_request_kbytes,
             round(s.buffer_gets /  nullif(s.executions, 0), 4) BufferGets_per_Exec
             s.executions,
             to_char(s.last_active_time,'dd/mm/yyyy hh24:mi:ss') last_act_time,
             s.first_load_time,
             s.sql_fulltext,             
             s.sql_profile,
             s.sql_patch,
             s.sql_plan_baseline
FROM   gv$sql s
WHERE  1=1
and    s.parsing_schema_name in ('LIST OF DATABASE USERS YOU WANT TO MONITOR')
order  by s.last_active_time desc;  
`

它会根据你的平均阈值很好地了解你的表现。

【讨论】:

以上是关于如何在 Oracle 12c 中跟踪 sql 查询?的主要内容,如果未能解决你的问题,请参考以下文章

将 SQL 查询转换为 PL/SQL 可以提高 Oracle 12c 中的性能吗? [关闭]

重命名时Oracle 12C审核触发器

Oracle 12c文档,用于SQL的更改/新功能

为啥 Oracle 12c 查询需要在表周围加上双引号 [重复]

需要帮助在 12c 中优化 Oracle 查询

如何查看oracle服务器上正在执行的SQL语句