Oracle 11g R2性能优化 SQL TRACE
作为Oracle官方自带的一种基本性能诊断工具,SQL Trace可以用来评估当前正在运行的SQL语句的效率,同时为该语句生成统计信息等,并保存这些信息到指定路径下的跟踪文件(trace)当中。SQL Trace会将一条SQL语句或者PL/SQL包执行过程全部输出到跟踪文件(trace)当中,可以通过分析跟踪文件(trace)来分析SQL语句的执行效率并进行性能诊断与优化。
通常来说trace文件的内容不易于理解与阅读,Oracle官方还提供了工具tkprof对trace文件进行格式化处理,本文不讨论tkprof工具的使用。之前在工作中也有使用过SQL Trace进行SQL语句的跟踪诊断,但都没有进行完整的总结,本文就SQL Trace工具的使用进行梳理。
环境准备
- 操作系统(OS):CentOS Linux release 7.5.1804 (Core)
 - 数据库版本(Oracle Database):Oracle Database 11g R2(11.2.0.4.0)
 
同时配置了示例SCHEMA和解锁了用户SCOTT、HR。
跟踪方式
开启SQL Trace有如下几种场景与方式:
- 当前会话开启跟踪本会话;
 - 当前会话开启跟踪其他会话;
 - 使用DBMS_MONITOR包来开启跟踪;
 - 根据登录触发器来开启跟踪。
 
当前会话跟踪
最简单的方法是在SQL*PLUS当中执行如下语句:
- 开启:
 
-- 配置trace文件的标识符便于寻找定位
SYS@dbabd> alter session set tracefile_identifier = dbabd;
-- 开启当前会话跟踪
SYS@dbabd> alter session set sql_trace = true;
通过运行以上语句就开启了当前会话的跟踪,trace文件位于 $ORACLE_BASE/diag/rdbms/dbabd/dbabd/trace目录下:
$ pwd
/data/app/oracle/diag/rdbms/dbabd/dbabd/trace
$ ls *DBABD*
dbabd_ora_27978_DBABD.trc  dbabd_ora_27978_DBABD.trm
以上得到trace文件当中并不包含绑定变量值,也不包含等待事件信息,如果需要这些信息,可以使用DBMS_SESSION包来开启跟踪,前提是用户必须有ALTER SESSION权限,否则会报ORA-01031: insufficient privileges错误。关于DBMS_SESSION包的用法可以参考官方文档:DBMS_SESSION
如果事先没有配置trace文件的标识符,则可以通过以下语句进行定位:
- 定位:
 
-- 语句
select tracefile
  from v$session s
  join v$process p
    on p.addr = s.paddr
 where s.audsid = USERENV('SESSIONID');
-- 结果
SYS@dbabd> select tracefile
  2    from v$session s
  3    join v$process p
  4      on p.addr = s.paddr
  5   where s.audsid = USERENV('SESSIONID');
TRACEFILE
----------------------------------------------------------------------------------------------------
/data/app/oracle/diag/rdbms/dbabd/dbabd/trace/dbabd_ora_27978_DBABD.trc
有时需要确认当前会话是否开启了跟踪,可以使用如下语句查询:
- 查询:
 
-- 语句
select s.sql_trace,
       s.sql_trace_waits,
       s.sql_trace_binds,
       traceid,
       tracefile
  from v$session s
  join v$process p
    on p.addr = s.paddr
 where s.audsid = USERENV('SESSIONID');
-- 结果
SYS@dbabd> select s.sql_trace,
  2         s.sql_trace_waits,
  3         s.sql_trace_binds,
  4         traceid,
  5         tracefile
  6    from v$session s
  7    join v$process p
  8      on p.addr = s.paddr
  9   where s.audsid = USERENV('SESSIONID');
SQL_TRACE  SQL_TRACE_WAITS SQL_TRACE_BINDS TRACEID    TRACEFILE
---------- --------------- --------------- ---------- ------------------------------------------------------------
ENABLED   FALSE           FALSE           DBABD      /data/app/oracle/diag/rdbms/dbabd/dbabd/trace/dbabd_ora_2797
                                                      8_DBABD.trc
如果需要关闭当前会话跟踪,则执行如下语句:
- 关闭
 
SYS@dbabd> alter session set sql_trace = false;
其他会话跟踪
如果是通过当前会话开启对其他会话的跟踪,一般都由DBA通过SYS用户操作,可以使用DBMS_SYSTEM包当中一个存储过程SET_SQL_TRACE_IN_SESSION,前提是需要获取到会话的SID和SERIAL#。
- 查看DBMS_SYSTEM包当中的结构
 
SYS@dbabd> desc dbms_system
…………省略…………
PROCEDURE SET_EV
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SI                             BINARY_INTEGER          IN
 SE                             BINARY_INTEGER          IN
 EV                             BINARY_INTEGER          IN
 LE                             BINARY_INTEGER          IN
 NM                             VARCHAR2                IN
…………省略…………
PROCEDURE SET_SQL_TRACE_IN_SESSION
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SID                            NUMBER                  IN
 SERIAL#                        NUMBER                  IN
 SQL_TRACE                      BOOLEAN                 IN
- 获取其他会话的SID和SERIAL#
 
SYS@dbabd> select sid,SERIAL#,username from v$session where username is not null;
       SID    SERIAL# USERNAME
---------- ---------- ------------------------------------------------------------------------------------------
       125         17 SYS
       141         45 SCOTT
实际环境当中可能出现同一个用户有多个会话存在,需要根据v$session视图当中的其他选项进行判断,这里假设只有一个SCOTT用户会话。
- 开启对SCOTT用户会话的跟踪
 
SYS@dbabd> begin
  2    dbms_system.SET_SQL_TRACE_IN_SESSION(SID => 141,
  3                                         SERIAL# => 45,
  4                                         SQL_TRACE => true
  5    );
  6  end;
  7  /
PL/SQL procedure successfully completed.
或
SYS@dbabd> exec dbms_system.SET_SQL_TRACE_IN_SESSION(141,45,true);
PL/SQL procedure successfully completed.
- 定位跟踪的trace文件
 
SYS@dbabd> select s.sql_trace,
  2         s.sql_trace_waits,
  3         s.sql_trace_binds,
  4         traceid,
  5         tracefile
  6    from v$session s
  7    join v$process p
  8      on p.addr = s.paddr
  9   where s.sid = 141;
SQL_TRACE  SQL_TRACE_WAITS SQL_TRACE_BINDS TRACEID    TRACEFILE
---------- --------------- --------------- ---------- ------------------------------------------------------------
ENABLED    FALSE           FALSE           SCOTT      /data/app/oracle/diag/rdbms/dbabd/dbabd/trace/dbabd_ora_1014
                                                      _SCOTT.trc
- 关闭对SCOTT用户会话的跟踪
 
SYS@dbabd> exec dbms_system.SET_SQL_TRACE_IN_SESSION(141,45,false);
PL/SQL procedure successfully completed.
DBMS_MONITOR包跟踪
无论是跟踪当前会话或者其他会话都可以采用DBMS_MONITOR包当中的SESSION_TRACE_ENABLE存储过程。跟踪其他会话的前提还是需要获取到会话的SID和SERIAL#,关闭则使用包当中的SESSION_TRACE_DISABLE存储过程。
存储过程SESSION_TRACE_ENABLE参数需求如下,详细可参考官方文档:SESSION_TRACE_ENABLE Procedure:
PROCEDURE SESSION_TRACE_ENABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SESSION_ID                     BINARY_INTEGER          IN     DEFAULT    -- 对应SID
 SERIAL_NUM                     BINARY_INTEGER          IN     DEFAULT    -- 对应SERIAL#
 WAITS                          BOOLEAN                 IN     DEFAULT    -- 对应是否加入等待事件跟踪
 BINDS                          BOOLEAN                 IN     DEFAULT    -- 对应是否加入绑定变量跟踪
 PLAN_STAT                      VARCHAR2                IN     DEFAULT    -- 对应跟踪转储行数据频率,取值参考官方文档
存储过程SESSION_TRACE_DISABLE参数需求如下,详细可参考官方文档:SESSION_TRACE_DISABLE Procedure:
PROCEDURE SESSION_TRACE_DISABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SESSION_ID                     BINARY_INTEGER          IN     DEFAULT
 SERIAL_NUM                     BINARY_INTEGER          IN     DEFAULT
从以上两个存储过程所需参数来看,如果是跟踪当前会话的话可以省略SESSION_ID和SERIAL_NUM这两个参数,具体的开启和关闭语句可以参考其他会话跟踪当中的DBMS_SYSTEM包使用方法。
当前数据库跟踪
使用DBMS_MONITOR包还可以用来开启整个数据库的跟踪,但是这会造成trace文件异常庞大,不便于定位具体问题,而且也会造成一定的性能损失,所以通常不建议开启。
采用SQL语句方式:
-- 开启
SYS@dbabd> alter system set sql_trace = true;
-- 关闭
SYS@dbabd> alter system set sql_trace = false;
采用DBMS_MONITOR包方式,主要使用DATABASE_TRACE_ENABLE和DATABASE_TRACE_DISABLE两个存储过程:
PROCEDURE DATABASE_TRACE_ENABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 WAITS                          BOOLEAN                 IN     DEFAULT
 BINDS                          BOOLEAN                 IN     DEFAULT
 INSTANCE_NAME                  VARCHAR2                IN     DEFAULT
 PLAN_STAT                      VARCHAR2                IN     DEFAULT
PROCEDURE DATABASE_TRACE_DISABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 INSTANCE_NAME                  VARCHAR2                IN     DEFAULT
-- 开启
SYS@dbabd> exec dbms_monitor.DATABASE_TRACE_ENABLE(true,true,'dbabd','all_executions');
-- 关闭
SYS@dbabd> exec dbms_monitor.DATABASE_TRACE_DISABLE('dbabd');
采用登录触发器跟踪
可以通过创建登录触发器来跟踪某个用户的SQL执行效率情况,登录触发器会在会话初始化的时候去执行,触发器可以根据指定条件是否对这次会话开启跟踪,以下登录触发器是以SCOTT用户为例,为SCOTT用户登录的所有会话设置合适的trace文件标识符并开启跟踪。
-- 创建触发器SCOTT_LOGIN_TRACE语句
create or replace trigger scott_login_trace
	after logon on database
begin
	if user = 'SCOTT'
	then
		execute immediate 'alter session set tracefile_identifier = SCOTT';
		dbms_session.session_trace_enable(waits => true, binds => true, plan_stat => 'all_executions');
	end if;
end;
/
使用SYS用户进行创建:
SYS@dbabd> create or replace trigger scott_login_trace
  2  after logon on database
  3  begin
  4  if user = 'SCOTT'
  5  then
  6  execute immediate 'alter session set tracefile_identifier = SCOTT';
  7  dbms_session.session_trace_enable(waits => true,
  8                                    binds => true,
  9                                    plan_stat => 'all_executions'
 10  );
 11  end if;
 12  end;
 13  /
Trigger created.
查看触发器状态:
SYS@dbabd> select owner,trigger_name,status,trigger_body from all_triggers where owner = 'SYS' and trigger_name = 'SCOTT_LOGIN_TRACE';
OWNER      TRIGGER_NAME         STATUS     TRIGGER_BODY
---------- -------------------- ---------- --------------------------------------------------------------------------------
SYS        SCOTT_LOGIN_TRACE    ENABLED    begin
                                           if user = 'SCOTT'
                                           then
                                           execute immediate 'alter session set tracefile_identifier = SCOTT';
                                           dbms_session.session_trace_enable(waits => true, binds => true, plan_stat => 'all_executions');
                                           end if;
                                           end;
创建完触发器之后,SCOTT用户只要一登录就会默认开启跟踪。
总结
以上梳理了常见的开启SQL TRACE的几种方式,但是原始的trace文件可读性比较差,通常不会直接去读取,而是通过工具tkprof进行格式化之后进行阅读,关于tkprof的使用可以参考我另一篇博文:Oracle 11g R2性能优化 tkprof
参考
https://docs.oracle.com/cd/E11882_01/server.112/e41573/sqltrace.htm#PFGRF010
https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_sessio.htm#ARPLS054
https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_monitor.htm#ARPLS091
☆〖本人水平有限,文中如有错误还请留言批评指正!〗☆
Oracle 11g R2性能优化 SQL TRACE的更多相关文章
- Oracle 11g R2性能优化 10046 event
		
作为SQL Trace的扩展功能,Oracle 10046 event(10046事件)是一个重要的调试事件,也可以说是系统性能分析时最重要的一个事件,它包含比SQL Trace更多的信息.但可惜的是 ...
 - Oracle 11g R2性能优化 tkprof
		
另一篇博文总结了关于SQL TRACE工具的使用方式,但是产生的trace文件格式阅读起来并不是十分友好,为了更好的分析trace文件,Oracle也自带了一个格式化工具tkprof.tkprof工具 ...
 - 全网最详细的Windows系统里Oracle 11g R2 Client客户端(64bit)安装后的初步使用(图文详解)
		
不多说,直接上干货! 前期博客 全网最详细的Windows系统里Oracle 11g R2 Client(64bit)的下载与安装(图文详解) 命令行方式测试安装是否成功 1) 打开服务(cmd— ...
 - 全网最详细的Windows系统里Oracle 11g R2 Database(64bit)安装后的初步使用(图文详解)
		
不多说,直接上干货! 前期博客 全网最详细的Windows系统里Oracle 11g R2 Database(64bit)的下载与安装(图文详解) 命令行方式测试安装是否成功 1) 打开服务(cm ...
 - Oracle 11g r2 Enterprise Manager (EM) 中文页面调整为英文页面
		
Oracle 11g r2 Enterprise Manager (EM) 在中文语言环境下, 部分功能(如包含时间的查询数据库实例: orcl > 指导中心 > SQL 优化概要 ...
 - CentOS 7 下oracle 11G R2 ADG 搭建
		
本文记录ADG搭建操作步骤,首先在虚拟机CentOS中安装并配置好oracle 11g R2(具体安装步骤在我的另一篇博客中),然后拷贝一份虚拟机,修改新虚拟机的主机名和ip配置,这时候主库和备库是一 ...
 - Oracle 11g R2创建数据库之手工建库方式
		
在之前的博文当中梳理了关于DBCA静默方式创建数据库的过程,本文就手工通过SQL*PLUS客户端采用CREATE DATABASE语句创建数据库.这种建库方式就是完全使用手工SQL语句创建数据库,通常 ...
 - Oracle 11g R2创建数据库之DBCA静默方式
		
通常创建Oracle数据库都是通过DBCA(Database Configuration Assistant)工具完成的,DBCA工具可以通过两种方式完成建库任务,即图形界面方式和静默命令行方式.既然 ...
 - centos 安装oracle 11g r2(三)-----表空间创建
		
centos 安装oracle 11g r2(三)-----表空间创建 创建表空间前要保证监听与数据库实例已经启动 1.启动监听 [oracle@localhost ~]$ lsnrctl start ...
 
随机推荐
- Android 后台应用保活、消息推送
			
3.针对以往Android版本的各种保活技术回顾 Android P之前为了搞定客户的投诉:“为什么微信能收到消息而你们的IM却不能?”,为了解决这个“痛点”,广大的Android开发者们只能让各种黑 ...
 - Swift GCD的使用1
			
typealias Task = (cancel : Bool) -> () func delay(time : NSTimeInterval, task : () -> ()) -> ...
 - chromedriver与chrome版本映射表
			
问题: 利用selenium调用谷歌浏览器时报错,后发现是由于浏览器与浏览器驱动不匹配造成的 C:\Users\\Desktop\selenium>python chrome.py[9956:6 ...
 - spark rdd df dataset
			
RDD.DataFrame.DataSet的区别和联系 共性: 1)都是spark中得弹性分布式数据集,轻量级 2)都是惰性机制,延迟计算 3)根据内存情况,自动缓存,加快计算速度 4)都有parti ...
 - stm32位操作详解
			
stm32位操作详解 STM32位操作原理 思想:把一个比特分成32位,每位都分配一个地址,这样就有32个地址,通过地址直接访问. 位操作基础 位运算 位运算的运算分量只能是整型或字符型数据,位运算把 ...
 - SQL Server Report Server 报表用户权限T-SQL查询
			
/************************************************************************** 查询用户在报表上的权限 ************ ...
 - 英语口语练习系列-C37-服饰-询问年龄-沁园春-长沙
			
服饰 clothes or jewelry your favorite clothes or jewelry jewelry necklace bracelet earrings gold diamo ...
 - 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习2
			
#include <iostream> #include <cctype> using namespace std; const int MAXSIZE=10; int mai ...
 - Vue(二十六)父子组件通信
			
今天写了一个分页公共组件,就出现了父子组件通信的问题,今天来总结下我遇到的父子组件通信问题 一.子组件调取父组件的数据或方法 (1)props 想要把父组件的值,传到子组件中,使用props 比如你在 ...
 - Spark on Yarn with HA
			
Spark 可以放到yarn上面去跑,这个毫无疑问.当Yarn做了HA的时候,网上会告诉你基本Spark测不需做太多的关注修改,实际不然. 除了像spark.yarn开头的相关配置外,其中一个很重要的 ...