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工具的使用进行梳理。 环境准备
同时配置了示例SCHEMA和解锁了用户SCOTT、HR。 跟踪方式开启SQL Trace有如下几种场景与方式:
当前会话跟踪最简单的方法是在SQL*PLUS当中执行如下语句:
-- 配置trace文件的标识符便于寻找定位 [email?protected]> alter session set tracefile_identifier = dbabd; -- 开启当前会话跟踪 [email?protected]> 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包来开启跟踪,前提是用户必须有 如果事先没有配置trace文件的标识符,则可以通过以下语句进行定位:
-- 语句 select tracefile from v$session s join v$process p on p.addr = s.paddr where s.audsid = USERENV('SESSIONID'); -- 结果 [email?protected]> 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'); -- 结果 [email?protected]> 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 如果需要关闭当前会话跟踪,则执行如下语句:
[email?protected]> alter session set sql_trace = false; 其他会话跟踪如果是通过当前会话开启对其他会话的跟踪,一般都由DBA通过SYS用户操作,可以使用DBMS_SYSTEM包当中一个存储过程SET_SQL_TRACE_IN_SESSION,前提是需要获取到会话的SID和SERIAL#。
[email?protected]> 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
[email?protected]> select sid,SERIAL#,username from v$session where username is not null; SID SERIAL# USERNAME ---------- ---------- ------------------------------------------------------------------------------------------ 125 17 SYS 141 45 SCOTT 实际环境当中可能出现同一个用户有多个会话存在,需要根据v$session视图当中的其他选项进行判断,这里假设只有一个SCOTT用户会话。
[email?protected]> 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. 或 [email?protected]> exec dbms_system.SET_SQL_TRACE_IN_SESSION(141,45,true); PL/SQL procedure successfully completed.
[email?protected]> select s.sql_trace,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
[email?protected]> exec dbms_system.SET_SQL_TRACE_IN_SESSION(141,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语句方式: -- 开启 [email?protected]> alter system set sql_trace = true; -- 关闭 [email?protected]> 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 -- 开启 [email?protected]> exec dbms_monitor.DATABASE_TRACE_ENABLE(true,true,'dbabd','all_executions'); -- 关闭 [email?protected]> 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用户进行创建: [email?protected]> 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. 查看触发器状态: [email?protected]> 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,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 ☆〖本人水平有限,文中如有错误还请留言批评指正!〗☆ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |