SQL调优指南笔记23:Performing Application Tracing

Posted dingdingfish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL调优指南笔记23:Performing Application Tracing相关的知识,希望对你有一定的参考价值。

本文为SQL Tuning Guide 第23章“Performing Application Tracing”的笔记。

本章解释什么是端到端应用程序跟踪,以及如何生成和读取跟踪文件。

重要基本概念

23.1 Overview of End-to-End Application Tracing

端到端的应用程序跟踪可以通过客户端标识符、服务、模块、操作、会话、实例或整个数据库来识别过度数据库工作负载的来源,例如高负载 SQL 语句。

在多层环境中,中间层将来自终端客户端的请求路由到不同的数据库会话,这使得跨数据库会话跟踪客户端变得困难。 端到端应用程序跟踪是一种基础结构,它使用客户端 ID 通过所有层唯一地跟踪特定的最终客户端到数据库,并提供有关最终客户端在数据库中执行的操作的信息。

23.1.1 Purpose of End-to-End Application Tracing

端到端应用程序跟踪简化了多层环境中性能问题的诊断。

例如,您可以找出数据库工作负载过大的来源,例如高负载 SQL 语句,并联系负责的用户。 此外,遇到问题的用户可以与您联系。 然后,您可以确定此用户会话在 PDB 级别执行的操作

端到端应用程序跟踪还通过跟踪服务中的特定模块和操作来简化应用程序工作负载的管理。 模块和动作名称由应用程序开发人员设置。 例如,您可以使用 DBMS_APPLICATION_INFO 包中的 SET_MODULE 和 SET_ACTION 过程在 PL/SQL 程序中设置这些值。

端到端应用程序跟踪可以识别数据库中的工作负载问题:

  • 客户端标识符
    根据登录 ID 指定最终用户,例如 HR.HR

  • 服务
    指定一组具有共同属性、服务级别阈值和优先级的应用程序; 或单个应用程序,例如用于会计应用程序的 ACCTG

  • 模块
    指定应用程序的功能模块,例如应收帐款或总帐

  • 行动
    指定模块中的操作,例如 INSERT 或 UPDATE 操作

  • 会议
    在本地实例上指定基于给定数据库会话标识符 (SID) 的会话

  • 实例
    根据实例名称指定给定的数据库实例

  • 容器
    指定容器

23.1.2 End-to-End Application Tracing for PDBs

V$ 视图允许读取特定于容器的跟踪文件。

主要用例如下:

  • CDB 管理员必须查看来自特定 PDB 的跟踪文件。
    V$DIAG_TRACE_FILE 视图列出了 ADR 跟踪目录中的所有跟踪文件,这些文件包含来自特定 PDB 的跟踪数据。 V$DIAG_TRACE_FILE_CONTENTS 显示跟踪文件的内容。

  • PDB 管理员必须查看来自特定 PDB 的跟踪文件。
    您可以使用 SQL Trace 为在 PDB 应用程序中执行的 SQL 语句收集诊断数据。 跟踪数据包括 SQL 跟踪(事件 10046)和优化器跟踪(事件 10053)。 使用 V$ 视图,开发人员可以只访问 SQL 或优化器跟踪记录,而无需访问整个跟踪文件

为了使用户和工具能够确定哪个 PDB 与文件或文件的一部分相关联,PDB 注释存在于跟踪文件、事件转储和日志文件中。 PDB 信息是存储在每个跟踪文件的 .trm 文件中的结构化元数据的一部分。 每条记录都包含以下属性:

  • CON_ID,这是与数据关联的容器的ID
  • CON_UID,这是容器的唯一ID
  • NAME,这是容器的名称

23.1.3 Tools for End-to-End Application Tracing

SQL 跟踪工具TKPROF两个基本的性能诊断工具,可以帮助您准确评估应用程序运行的 SQL 语句的效率。

为获得最佳结果,请将这些工具与 EXPLAIN PLAN 一起使用,而不是单独使用 EXPLAIN PLAN。 跟踪信息写入文件后,您可以使用 TRCSESS 实用程序合并此数据,然后使用 TKPROF 或 SQL Trace 对其进行诊断

端到端应用程序跟踪的推荐接口是 Oracle Enterprise Manager Cloud Control (Cloud Control)。 使用 Cloud Control,您可以查看每种消费者类型的顶级消费者,并为特定消费者启用或禁用统计信息收集和 SQL 跟踪。 如果 Cloud Control 不可用,则您可以使用 DBMS_MONITOR API 管理此功能

23.1.3.1 Overview of the SQL Trace Facility

SQL 跟踪工具提供有关各个 SQL 语句的性能信息。

SQL Trace 为每个语句生成以下统计信息:

  • 解析、执行和获取计数
  • CPU 和运行时间
  • 物理读和逻辑读
  • 处理的行数
  • 库缓存未命中
  • 每次解析发生的用户名
  • 每次提交和回滚
  • 每个 SQL 语句的等待事件数据,以及每个跟踪文件的摘要

如果 SQL 语句的游标关闭,则 SQL Trace 还会提供行源信息,其中包括:

  • 显示每条SQL语句实际执行计划的行操作
  • 行数、一致性读取数、物理读取数、物理写入数和行上每个操作所用的时间

虽然您可以为会话或实例启用 SQL 跟踪工具,但 Oracle 建议您改用 DBMS_SESSION 或 DBMS_MONITOR 程序包。 当为会话或实例启用 SQL 跟踪工具时,在用户会话或实例中执行的所有 SQL 语句的性能统计信息都将放入跟踪文件中。 使用 SQL 跟踪工具会影响性能,并可能导致系统开销增加、CPU 使用率过高和磁盘空间不足

TRCSESS 命令行实用程序根据特定条件(如会话或客户端 ID)整合来自多个跟踪文件的跟踪信息。

23.1.3.2 Overview of TKPROF

要格式化跟踪文件的内容并将输出放入可读的输出文件中,请运行 TKPROF 程序。

TKPROF 还可以执行以下操作:

  • 创建将统计信息存储在数据库中的 SQL 脚本
  • 确定SQL语句的执行计划

TKPROF 报告每条执行的语句所消耗的资源、它被调用的次数以及它处理的行数。 此信息使您能够找到那些使用最多资源的语句。 有了可用的基线,您可以评估所使用的资源在给定的工作情况下是否合理。

23.2 Enabling Statistics Gathering for End-to-End Tracing

要使用 PL/SQL 收集适当的统计信息,您必须使用 DBMS_MONITOR 中的过程为客户端标识符、服务、模块或操作启用统计信息收集。

默认级别是会话级统计信息收集。 统计信息收集对于数据库是全局的,并在数据库实例重新启动后继续。

23.2.1 Enabling Statistics Gathering for a Client ID

CLIENT_ID_STAT_ENABLE 过程为给定的客户端 ID 启用统计信息收集,而 CLIENT_ID_STAT_DISABLE 过程禁用它。

您可以在 V$SESSION 的 CLIENT_IDENTIFIER 列中查看客户端标识符。

假定您要为 ID 为 oe.oe 的客户端启用然后禁用统计信息收集。

-- 为 oe.oe 启用统计信息收集。
EXECUTE DBMS_MONITOR.CLIENT_ID_STAT_ENABLE(client_id => 'OE.OE');
-- 为 oe.oe 禁用统计信息收集。
EXECUTE DBMS_MONITOR.CLIENT_ID_STAT_DISABLE(client_id => 'OE.OE');

23.2.2 Enabling Statistics Gathering for Services, Modules, and Actions

过程 SERV_MOD_ACT_STAT_ENABLE 启用服务、模块和操作组合的统计信息收集,而过程 SERV_MOD_ACT_STAT_DISABLE 禁用服务、模块和操作组合的统计信息收集。

当您使用前面的 DBMS_MONITOR 过程更改模块或操作时,更改将在会话中执行下一个用户调用时生效。 例如,如果模块在会话中设置为 module1,并且如果模块在会话中的用户调用中重置为 module2,则模块在该用户调用期间保持为 module1。 在会话中的下一个用户调用中,模块更改为 module2。

-- 启用
BEGIN 
  DBMS_MONITOR.SERV_MOD_ACT_STAT_ENABLE(
    service_name => 'ACCTG'   
,   module_name  => 'PAYROLL' );
END;

BEGIN 
  DBMS_MONITOR.SERV_MOD_ACT_STAT_ENABLE(
    service_name => 'ACCTG'      
,   module_name  => 'GLEDGER'     
,   action_name  => 'INSERT ITEM' );
END;

-- 禁用
BEGIN 
  DBMS_MONITOR.SERV_MOD_ACT_STAT_DISABLE(
    service_name => 'ACCTG'       
,   module_name  => 'GLEDGER'     
,   action_name  => 'INSERT ITEM' );
END;

23.3 Enabling End-to-End Application Tracing

要启用对客户端标识符、服务、模块、操作、会话、实例或数据库的跟踪,请执行 DBMS_MONITOR 程序包中的适当过程。

根据您提供的条件,特定的跟踪信息会被捕获到一组跟踪文件中,并合并到一个输出跟踪文件中。 您可以通过以下条件为特定诊断和工作负载管理启用跟踪。

23.3.1 Enabling Tracing for a Client Identifier

-- 要启用和禁用对客户端标识符的跟踪
BEGIN 
  DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE(
    client_id => 'OE.OE' ,      
    waits     => true    ,      
    binds     => false   );
END;

-- 禁用
EXECUTE DBMS_MONITOR.CLIENT_ID_TRACE_DISABLE(client_id => 'OE.OE');

23.3.2 Enabling Tracing for a Service, Module, and Action

DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE 过程为数据库全局启用对服务名称、模块和操作的指定组合的 SQL 跟踪,除非该过程指定数据库实例名称。

SERV_MOD_ACT_TRACE_DISABLE 过程在全局禁用所有已启用实例的给定服务名称、模块和操作名称组合的跟踪。

-- 启用
BEGIN 
  DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE(
    service_name  => 'ACCTG'   ,
    module_name   => 'PAYROLL' ,
    waits         =>  true     ,
    binds         =>  false    ,
    instance_name => 'inst1'   );
END;

-- 禁用
BEGIN 
  DBMS_MONITOR.SERV_MOD_ACT_TRACE_DISABLE(
    service_name  => 'ACCTG'   ,
    module_name   => 'PAYROLL' ,
    instance_name => 'inst1'   );
END;

23.3.3 Enabling Tracing for a Session

SESSION_TRACE_ENABLE 过程在本地实例上启用给定数据库会话标识符 (SID) 的跟踪。

尽管 DBMS_MONITOR 包只能由具有 DBA 角色的用户调用,但用户还可以通过调用 DBMS_SESSION.SESSION_TRACE_ENABLE 过程为自己的会话启用 SQL 跟踪。

-- 为当前会话启用跟踪
BEGIN 
  DBMS_SESSION.SESSION_TRACE_ENABLE(
    waits => true
  , binds => false);
END;

-- 为指定会话启用跟踪
SELECT SID, SERIAL#, USERNAME 
FROM   V$SESSION
WHERE  USERNAME = 'OE';

       SID    SERIAL# USERNAME
---------- ---------- ------------------------------
        27         60 OE

BEGIN 
  DBMS_MONITOR.SESSION_TRACE_ENABLE(
    session_id => 27 
  , serial_num => 60
  , waits      => true
  , binds      => false);
END;

-- 为指定会话禁用跟踪
BEGIN
  DBMS_MONITOR.SESSION_TRACE_DISABLE(
    session_id => 27
  , serial_num => 60);
END;

23.3.4 Enabling Tracing for an Instance or Database

DBMS_MONITOR.DATABASE_TRACE_ENABLE 过程覆盖所有其他会话级跟踪,但它是对客户端标识符、服务、模块和操作跟踪的补充。 为所有当前和未来会话启用跟踪。

所有新会话都继承此过程指定的等待和绑定信息,直到您调用 DATABASE_TRACE_DISABLE 过程。 当您使用 instance_name 参数调用此过程时,该过程会重置命名实例的会话级 SQL 跟踪。 如果您在没有 instance_name 参数的情况下调用此过程,则该过程将重置整个数据库的会话级 SQL 跟踪。

先决条件:您必须具有管理权限才能执行 DATABASE_TRACE_ENABLE 过程。

-- 启用
BEGIN 
  DBMS_MONITOR.DATABASE_TRACE_ENABLE(
    waits         => true
  , binds         => false
  , instance_name => 'inst1' );
END;

-- 禁用
EXECUTE DBMS_MONITOR.DATABASE_TRACE_DISABLE(instance_name => 'inst1');

-- 整库禁用
EXECUTE DBMS_MONITOR.DATABASE_TRACE_DISABLE();

23.4 Generating Output Files Using SQL Trace and TKPROF

本节介绍使用 SQL Trace 和 TKPROF 的基本过程。
生成输出文件的过程如下:

  1. 设置跟踪文件管理的初始化参数。
  2. 为所需的会话启用 SQL 跟踪工具,然后运行该应用程序。 此步骤生成一个跟踪文件,其中包含应用程序发出的SQL 语句的统计信息。
  3. 运行 TKPROF 将在步骤 2 中创建的跟踪文件转换为可读的输出文件。 此步骤可以选择创建一个 SQL脚本,您可以使用该脚本将统计信息存储在数据库中。
  4. 或者,运行在步骤 3 中生成的 SQL 脚本以将统计信息存储在数据库中。

23.4.1 Step 1: Setting Initialization Parameters for Trace File Management

要启用跟踪文件,您必须确保设置了特定的初始化参数。

当为会话启用 SQL 跟踪工具时,Oracle 数据库生成一个跟踪文件,其中包含该会话的跟踪 SQL 语句的统计信息。 当为实例启用 SQL 跟踪工具时,Oracle 数据库会为每个进程创建一个单独的跟踪文件

设置跟踪文件管理的初始化参数:

  1. 检查 TIMED_STATISTICS、MAX_DUMP_FILE_SIZE 和 DIAGNOSTIC_DEST 初始化参数的设置,如“表 23-1”所示。
参数描述
DIAGNOSTIC_DEST指定自动诊断存储库 (ADR) 主页的位置。 每个数据库实例的诊断文件都位于这个专用目录中。
MAX_DUMP_FILE_SIZE当在数据库实例级别启用 SQL 跟踪工具时,对数据库的每次调用都会在操作系统文件格式的文件中写入一行文本。 操作系统块中这些文件的最大大小受此初始化参数的限制。 默认为无限制。
TIMED_STATISTICS通过 SQL 跟踪工具启用和禁用定时统计信息的收集,例如 CPU 和运行时间,以及 V$ 视图中各种统计信息的收集。
如果 STATISTICS_LEVEL 设置为 TYPICAL 或 ALL,则 TIMED_STATISTICS 的默认值为真。 如果 STATISTICS_LEVEL 设置为 BASIC,则 TIMED_STATISTICS 的默认值为 false。
启用计时会导致对低级操作的额外计时调用。 这是一个动态参数。 它也是一个会话参数。
  1. 设计一种识别生成的跟踪文件的方法。
    确保您知道如何通过名称区分跟踪文件。 您可以通过在程序中包含诸如 SELECT program_name FROM DUAL 之类的语句来标记跟踪文件。 然后,您可以将每个文件追溯到创建它的过程。
    您还可以设置 TRACEFILE_IDENTIFIER 初始化参数以指定成为跟踪文件名一部分的自定义标识符。
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'my_trace_id';
  1. 如果操作系统保留文件的多个版本,则确保版本限制足够高以容纳您希望 SQL 跟踪工具生成的跟踪文件的数量。

  2. 如果生成的跟踪文件可能属于您以外的操作系统用户,请确保您拥有使用 TKPROF 格式化它们的必要权限。

23.4.2 Step 2: Enabling the SQL Trace Facility

您可以在实例或会话级别启用 SQL 跟踪工具。

要使用的包取决于级别:

  • 数据库实例
    使用 DBMS_MONITOR.DATABASE_TRACE_ENABLE 过程启用跟踪,使用 DBMS_MONITOR.DATABASE_TRACE_DISABLE 过程禁用跟踪。

  • 数据库会话
    使用 DBMS_SESSION.SET_SQL_TRACE 过程启用跟踪 (true) 或禁用跟踪 (false)。

注意:因为运行 SQL Trace 工具会增加系统开销,所以只在调整 SQL 语句时启用它,并在完成后禁用它。

-- 数据库层面
EXEC DBMS_MONITOR.DATABASE_TRACE_ENABLE(INSTANCE_NAME => 'orcl');
EXEC DBMS_MONITOR.DATABASE_TRACE_DISABLE(INSTANCE_NAME => 'orcl');

-- 会话级层面
EXEC DBMS_SESSION.SET_SQL_TRACE(sql_trace => true);
EXEC DBMS_SESSION.SET_SQL_TRACE(sql_trace => false);

23.4.3 Step 3: Generating Output Files with TKPROF

TKPROF 接受 SQL 跟踪工具生成的跟踪文件作为输入,并生成格式化的输出文件。 TKPROF 还可以生成执行计划。

在 SQL 跟踪工具生成跟踪文件后,您可以:

  • 在每个单独的跟踪文件上运行 TKPROF,生成多个格式化的输出文件,每个会话一个。
  • 连接跟踪文件,然后对结果运行 TKPROF 以生成整个实例的格式化输出文件。
  • 运行 TRCSESS 命令行实用程序以合并来自多个跟踪文件的跟踪信息,然后对结果运行 TKPROF。

TKPROF 不报告跟踪文件中记录的 COMMIT 和 ROLLBACK 语句。

注意:以下 SQL 语句在 SQL Trace 文件中被截断为 25 个字符:

SET ROLE
GRANT
ALTER USER
ALTER ROLE
CREATE USER
CREATE ROLE

示例 23-1 TKPROF 输出

SELECT * FROM emp, dept 
WHERE emp.deptno = dept.deptno;

call   count      cpu    elapsed     disk    query current    rows
---- -------  -------  --------- -------- -------- -------  ------
Parse      1     0.16      0.29         3       13       0       0
Execute    1     0.00      0.00         0        0       0       0
Fetch      1     0.03      0.26         2        2       4      14 
 
Misses in library cache during parse: 1 
Parsing user id: (8) SCOTT 

Rows     Execution Plan
-------  --------------------------------------------------- 14  MERGE JOIN
 4   SORT JOIN
 4     TABLE ACCESS (FULL) OF 'DEPT'
14    SORT JOIN
14      TABLE ACCESS (FULL) OF 'EMP'

对于此语句,TKPROF 输出包括以下信息:

  • SQL 语句的文本
  • 表格形式的 SQL Trace 统计信息
  • 语句解析和执行的库缓存未命中数。
  • 用户最初解析语句。
  • EXPLAIN PLAN生成的执行计划。

TKPROF 还为跟踪文件提供了用户级语句和递归 SQL 调用的摘要。

23.4.4 Step 4: Storing SQL Trace Facility Statistics

您可能希望保留 SQL 跟踪工具为应用程序生成的统计信息的历史记录,并随着时间的推移对它们进行比较。

TKPROF 可以生成一个 SQL 脚本,该脚本创建一个表并将统计数据行插入其中。 该脚本包含以下内容:

  • 创建名为 TKPROF_TABLE 的输出表的 CREATE TABLE 语句。
  • 向 TKPROF_TABLE 添加统计行的 INSERT 语句,每个跟踪的 SQL 语句一个。

运行 TKPROF 后,运行此脚本以将统计信息存储在数据库中。

23.4.4.1 Generating the TKPROF Output SQL Script

运行 TKPROF 时,使用 INSERT 参数指定生成的 SQL 脚本的名称。

如果省略 INSERT 参数,则 TKPROF 不会生成脚本。

23.4.4.2 Editing the TKPROF Output SQL Script

在 TKPROF 创建了 SQL 脚本之后,您可能希望在运行脚本之前对其进行编辑。

如果您已经为以前收集的统计信息创建了一个输出表,并且您想要向该表添加新的统计信息,那么请从脚本中删除 CREATE TABLE 语句。 该脚本然后将新行插入到现有表中。 如果您创建了多个输出表,可能是为了将来自不同数据库的统计信息存储在不同的表中,则编辑 CREATE TABLE 和 INSERT 语句以更改输出表的名称。

23.4.4.3 Querying the Output Table

创建输出表后,使用 SELECT 语句进行查询。

以下 CREATE TABLE 语句创建 TKPROF_TABLE:

CREATE TABLE TKPROF_TABLE (

DATE_OF_INSERT    DATE,
CURSOR_NUM        NUMBER,
DEPTH             NUMBER,
USER_ID           NUMBER,
PARSE_CNT         NUMBER,
PARSE_CPU         NUMBER,
PARSE_ELAP        NUMBER,
PARSE_DISK        NUMBER,
PARSE_QUERY       NUMBER,
PARSE_CURRENT     NUMBER,
PARSE_MISS        NUMBER,
EXE_COUNT         NUMBER,
EXE_CPU           NUMBER,
EXE_ELAP          NUMBER,
EXE_DISK          NUMBER,
EXE_QUERY         NUMBER,
EXE_CURRENT       NUMBER,
EXE_MISS          NUMBER,
EXE_ROWS          NUMBER,
FETCH_COUNT       NUMBER,
FETCH_CPU         NUMBER,
FETCH_ELAP        NUMBER,
FETCH_DISK        NUMBER,
FETCH_QUERY       NUMBER,
FETCH_CURRENT     NUMBER,
FETCH_ROWS        NUMBER,
CLOCK_TICKS       NUMBER,
SQL_STATEMENT     LONG);

大多数输出表列直接对应于格式化输出文件中出现的统计信息。 例如,PARSE_CNT 列值对应于输出文件中解析步骤的计数统计。

下表中的列可帮助您识别一行统计信息。

表 23-2 用于标识统计行的 TKPROF_TABLE 列

描述
SQL_STATEMENT这是 SQL 跟踪工具为其收集统计行的 SQL 语句。 因为此列的数据类型为 LONG,所以不能在表达式或 WHERE 子句条件中使用它。
DATE_OF_INSERT这是将行插入表中的日期和时间。 该值与 SQL 跟踪工具收集统计信息的时间不同。
DEPTH这指示发出 SQL 语句的递归级别。 例如,值为 0 表示用户发出了该语句。 值为 1 表示 Oracle 数据库生成该语句作为递归调用以处理值为 0 的语句(用户发出的语句)。 值 n 表示 Oracle 数据库生成语句作为递归调用以处理值为 n-1 的语句。
USER_ID这标识了发出语句的用户。 该值也出现在格式化的输出文件中。
CURSOR_NUMOracle 数据库使用此列值来跟踪每个 SQL 语句分配到的游标。

输出表不存储语句的执行计划。 以下查询返回输出表中的统计信息。

SELECT * FROM TKPROF_TABLE;

DATE_OF_INSERT CURSOR_NUM DEPTH USER_ID PARSE_CNT PARSE_CPU PARSE_ELAP
-------------- ---------- ----- ------- --------- --------- ---------- 
21-DEC-2017          1      0     8         1        16         22

PARSE_DISK PARSE_QUERY PARSE_CURRENT PARSE_MISS EXE_COUNT EXE_CPU 
---------- ----------- ------------- ---------- --------- ------- 
    3          11           0            1           1         0 

EXE_ELAP EXE_DISK EXE_QUERY EXE_CURRENT EXE_MISS EXE_ROWS FETCH_COUNT 
-------- -------- --------- ----------- -------- -------- ----------- 
    0        0        0          0          0        0         1 

FETCH_CPU FETCH_ELAP FETCH_DISK FETCH_QUERY FETCH_CURRENT FETCH_ROWS 
--------- ---------- ---------- ----------- ------------- ---------- 
     2        20          2          2            4           10 

SQL_STATEMENT 
---------------------------------------------------------------------
SELECT * FROM EMP, DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO 

23.5 Guidelines for Interpreting TKPROF Output

虽然 TKPROF 提供了有用的分析,但最准确的效率衡量标准是应用程序的性能。 TKPROF 输出的末尾是进程在跟踪运行期间执行的工作的摘要。

23.5.1 Guideline for Interpreting the Resolution of Statistics

时间统计的分辨率为百分之一秒。 因此,任何花费百分之一秒或更短时间的游标操作都可能无法准确计时。

在解释统计数据时,请记住时间限制。 在解释执行速度非常快的简单查询的结果时尤其要小心。

23.5.2 Guideline for Recursive SQL Statements

递归 SQL 是 Oracle 数据库为执行用户发出的 SQL 语句而必须发出的附加 SQL

从概念上讲,递归 SQL 是“副作用 SQL”。 例如,如果会话将一行插入到没有足够空间容纳该行的表中,则数据库会进行递归 SQL 调用以动态分配空间。 当数据字典信息在内存中不可用且因此必须从磁盘检索时,数据库还会生成递归调用。

如果在启用 SQL 跟踪工具时发生递归调用,则 TKPROF 会为递归 SQL 语句生成统计信息,并在输出文件中将它们清楚地标记为递归 SQL 语句。 您可以通过将 SYS 命令行参数设置为 NO 来禁止在输出文件中列出 Oracle 数据库内部递归调用(例如,空间管理)。 递归 SQL 语句的统计信息包含在该语句的列表中,而不是包含在导致递归调用的 SQL 语句的列表中。 因此,当您计算处理 SQL 语句所需的总资源时,请考虑该语句的统计信息以及该语句引起的递归调用的统计信息。

注意:SQL 级操作不包括递归 SQL 统计信息。

23.5.3 Guideline for Deciding Which Statements to Tune

您必须确定哪些 SQL 语句使用最多的 CPU 或磁盘资源

如果启用了 TIMED_STATISTICS 参数,那么您可以在 CPU 列中找到高 CPU 活动。 如果未启用 TIMED_STATISTICS,则检查 QUERY 和 CURRENT 列。

除了锁定问题和低效的 PL/SQL 循环之外,CPU 时间和运行时间都不是查找问题语句所必需的。 关键是块访问次数,既有query(即受读一致性约束)也有current(即不受读一致性约束)。 将要更新的段头和块以当前方式获取,但所有查询和子查询处理都以查询方式请求数据。 这些与实例统计 CONSISTENT GETS 和 DB BLOCK GETS 完全相同。 您可以在磁盘列中找到高磁盘活动。

以下清单显示了一条 SQL 语句的 TKPROF 输出,因为它出现在输出文件中:

SELECT * 
FROM emp, dept 
WHERE emp.deptno = dept.deptno;

call   count      cpu    elapsed     disk    query current    rows
---- -------  -------  --------- -------- -------- -------  ------
Parse     11     0.08      0.18        0       0       0         0
Execute   11     0.23      0.66        0       3       6         0
Fetch     35     6.70      6.83      100   12326       2       824
------------------------------------------------------------------
total     57     7.01      7.67      100   12329       8       826

Misses in library cache during parse: 0 

如果 7.01 CPU 秒和检索 824 行是可以接受的,那么您不需要进一步查看此跟踪输出。 事实上,TKPROF 报告在调优练习中的一个主要用途是从详细调优阶段消除流程。

输出表明进行了 10 次不必要的解析调用(因为此单个语句存在 11 次解析调用)并且执行了数组提取操作。 提取的行数多于执行的提取行数。 CPU 和经过的计时之间的较大差距表示存在物理 I/O

23.5.4 Guidelines for Avoiding Traps in TKPROF Interpretation

解释 TKPROF 输出时,有助于了解常见陷阱。

23.5.4.1 Guideline for Avoiding the Argument Trap

如果您不知道在运行时绑定的值,则可能会落入参数陷阱。

EXPLAIN PLAN 无法从 SQL 语句的文本中确定绑定变量的类型,它始终假定类型为 VARCHAR。 如果绑定变量实际上是数字或日期,则 TKPROF 会导致隐式数据转换,这会导致执行计划效率低下。 为避免这种情况,请在查询中尝试不同的数据类型,并自行执行转换。

23.5.4.2 Guideline for Avoiding the Read Consistency Trap

如果不知道未提交的事务对列进行了一系列更新,就很难理解为什么会发生如此多的块访问。

这种情况通常是不可重复的。 如果该流程再次运行,则另一个事务不太可能以相同的方式与它交互。

SELECT name_id
FROM cq_names 
WHERE name = 'FLOOR';

call     count     cpu     elapsed     disk     query current     rows
----     -----     ---     -------     ----     ----- -------     ----
Parse        1    0.10        0.18        0         0       0        0
Execute      1    0.00        0.00        0         0       0        0
Fetch        1    0.11        0.21        2       101       0        1

Misses in library cache during parse: 1
Parsing user id: 01 (USER1)

Rows     Execution Plan
----     --------- ----
   0     SELECT STATEMENT
   1       TABLE ACCESS (BY ROWID) OF 'CQ_NAMES'
   2         INDEX (RANGE SCAN) OF 'CQ_NAMES_NAME' (NON_UNIQUE) 

23.5.4.3 Guideline for Avoiding the Schema Trap

在某些情况下,一个明显简单的索引查询会查看许多数据库块并以当前模式访问它们。

以下示例显示了架构陷阱的极端(因此很容易检测到)示例:

SELECT name_id
FROM cq_names 
WHERE name = 'FLOOR';

call        count        cpu      elapsed     disk  query current rows
--------  -------   --------    ---------  ------- ------ ------- ----
Parse           1       0.06         0.10        0      0       0    0
Execute         1       0.02         0.02        0      0       0    0 
Fetch           1       0.23         0.30       31     31       3    1

Misses in library cache during parse: 0
Parsing user id: 02  (USER2)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT
   2340    TABLE ACCESS (BY ROWID) OF 'CQ_NAMES'
      0      INDEX (RANGE SCAN) OF 'CQ_NAMES_NAME' (NON-UNIQUE)

两个统计数据表明查询可能是通过全表扫描执行的:当前模式块访问,以及计划中来自表访问行源的行数。 解释是所需的索引是在生成跟踪文件之后但在运行 TKPROF 之前建立的。 生成新的跟踪文件会提供以下数据:

SELECT name_id
FROM cq_names 
WHERE name = 'FLOOR'; 

call    count    cpu   elapsed  disk  query current     rows
-----  ------ ------  -------- ----- ------ -------    -----
Parse       1   0.01      0.02     0      0       0        0
Execute     1   0.00      0.00     0      0       0        0
Fetch       1   0.00      0.00     0      2       0        1

Misses in library cache during parse: 0
Parsing user id: 02  (USER2)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT
      1    TABLE ACCESS (BY ROWID) OF 'CQ_NAMES'
      2      INDEX (RANGE SCAN) OF 'CQ_NAMES_NAME' (NON-UNIQUE)

在正确的版本中,解析调用占用了 10 毫秒的 CPU 时间和 20 毫秒的运行时间,但查询显然没有花时间来执行和执行提取。 出现这些异常是因为 10 毫秒的时钟滴答相对于执行和获取数据所花费的时间来说太长了。 在这种情况下,重要的是要多次执行语句,这样您才能获得统计上有效的数字。

23.5.4.4 Guideline for Avoiding the Time Trap

在某些情况下,查询会花费莫名其妙的长时间。

例如,以下 7 行的更新耗时19 秒:

UPDATE cq_names 
  SET ATTRIBUTES = lower(ATTRIBUTES)
  WHERE ATTRIBUTES = :att 

call       count       cpu    elapsed     disk    query current        rows
-------- -------  --------  --------- -------- -------- -------  ----------
Parse          1      0.06       0.24        0        0       0           0
Execute        1      0.62      19.62       22      526      12           7
Fetch          0      0.00       0.00        0        0       0           0

Misses in library cache during parse: 1
Parsing user id: 02  (USER2)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  UPDATE STATEMENT
   2519  TABLE ACCESS (FULL) OF 'CQ_NAMES'

解释是来自另一笔交易的干扰。 在这种情况下,另一个事务在更新发布前后的几秒钟内持有表 cq_names 的共享锁。 诊断干扰效应的发生需要经验。 一方面,当干扰仅造成较短的延迟(或前一个示例中块访问的小幅增加)时,比较数据是必不可少的。 但是,如果干扰仅产生适度的开销,并且语句本质上是有效的,则可能不需要分析其统计数据。

23.6 Application Tracing Utilities

Oracle 跟踪实用程序是 TKPROF 和 TRCSESS。

23.6.1 TRCSESS

TRCSESS 实用程序根据用户指定的标准合并来自选定跟踪文件的跟踪输出。

在 TRCSESS 将跟踪信息合并到单个输出文件后,TKPROF 可以处理输出文件。

23.6.1.1 Purpose

TRCSESS 对于出于性能或调试目的整合特定会话的跟踪很有用。

跟踪特定会话在专用服务器模型中通常不是问题,因为一个进程在其生命周期内服务于一个会话。 您可以从属于服务器进程的跟踪文件中看到会话的跟踪信息。 但是,在共享服务器配置中,随着时间的推移,用户会话由不同的进程提供服务。 用户会话的跟踪分散在属于不同进程的不同跟踪文件中,这使得很难全面了解会话的生命周期。

23.6.1.2 Guidelines

您必须指定 session、clientid、service、action 或 module 选项之一。

如果您指定多个选项,那么 TRCSESS 会将所有满足指定条件的跟踪文件合并到输出文件中。

23.6.1.3 Syntax

trcsess  [output=output_file_name]
         [session=session_id]
         [clientid=client_id]
         [service=service_name]
         [action=action_name]
         [module=module_name]
         [trace_files]

23.6.1.4 Options

TRCSESS 支持许多命令行选项。

以上是关于SQL调优指南笔记23:Performing Application Tracing的主要内容,如果未能解决你的问题,请参考以下文章

SQL调优指南笔记9:Joins

SQL调优指南笔记9:Joins

SQL调优指南笔记1:Introduction to SQL Tuning

SQL调优指南笔记6:Explaining and Displaying Execution Plans

SQL调优指南笔记11:Histograms

SQL调优指南笔记11:Histograms

(c)2006-2024 SYSTEM All Rights Reserved IT常识

参数描述