面试宝典:介绍下Oracle数据库动态性能视图 V$TOPLEVELCALL

在这里插入图片描述
好的,我们来对 Oracle 19C 数据库中的 V$TOPLEVELCALL 动态性能视图进行详尽、深入的解析。这是一个用于高级性能诊断、特别是理解 SQL 执行调用层次结构的关键视图。


1. 作用与概述

V$TOPLEVELCALL 视图用于跟踪和统计由最外层(顶级)用户调用所引发的数据库内部调用(递归SQL执行)的性能数据

  • 核心概念 - “顶级调用”(Top-Level Call): 指直接由客户端应用程序发起的 SQL 语句或 PL/SQL 调用。例如,一个 Java 应用程序执行的 SELECT * FROM employees
  • 核心概念 - “递归调用”(Recursive Call): 指为了完成“顶级调用”而由数据库内部自动执行的 SQL 语句。例如,执行上述 SELECT 时,如果数据缓冲区没有所需数据,Oracle 需要执行递归调用(递归SQL)从磁盘读取数据块到内存。此外,数据字典查询、空间分配(ALTER TABLE 分配区间)、PL/SQL 中的 SQL、触发器中的 SQL 等都可能是递归调用。
  • 视图目的: 此视图将递归调用的资源消耗(CPU、等待时间、物理读等)归属到其根源的顶级调用上。它回答了“这个复杂的用户操作(顶级调用),到底在数据库内部引发了哪些工作(递归调用),各自消耗了多少资源?”的问题。

2. 使用场景

此视图主要用于高级性能诊断和深度资源消耗分析:

  1. 诊断由递归SQL引起的性能问题

    • 当一个用户操作(如一个简单的 INSERT)执行得很慢,但 V$SQL 显示该语句本身消耗资源很少时,问题很可能出在递归SQL上。通过此视图可以定位到是哪个顶级调用导致了大量的递归执行,并量化其影响。
  2. 分析DDL操作的真实开销

    • CREATE INDEX, ALTER TABLE MOVE 等 DDL 命令会在内部执行大量递归SQL(查询数据字典、分配和初始化空间、构建索引结构等)。此视图可以揭示这些操作内部各个阶段(如空间管理调用)的详细开销。
  3. 理解PL/SQL执行的细节

    • 执行一个存储过程(顶级调用)会触发过程内部多条SQL语句的执行(递归调用)。此视图可以帮助分析过程的总开销在内部SQL上的分布。
  4. 全局资源审计

    • 更准确地评估一个应用程序操作(顶级调用)的总成本,包括其所有“隐藏”的递归成本。

3. 字段含义详解

V$TOPLEVELCALL 视图的字段围绕顶级调用ID和聚合的递归调用统计信息。

字段名称数据类型含义说明
TOP_LEVEL_CALL_IDNUMBER顶级调用的唯一标识符。这是整个调用树的根ID。在 V$SQLV$SESSION 等视图中,SQL 的 TOP_LEVEL_CALL_ID 字段指向此ID。
TOP_LEVEL_CALL_NAMEVARCHAR2(64)顶级调用的名称或类型。常见值:
PL/SQL EXECUTE
SELECT
INSERT
UPDATE
DELETE
CREATE INDEX (及其他DDL)
UNKNOWN
CALL_TYPEVARCHAR2(10)调用类型的简写。通常是 RECURSIVE,因为此视图主要统计递归调用。
CALL_CLASSVARCHAR2(18)调用的类别,提供了更细粒度的分类。例如:
RECURSIVE SPACE MGMT (空间管理递归SQL)
RECURSIVE SQL (一般的递归SQL)
PL/SQL
CPU_TIMENUMBER归属于此顶级调用的所有递归调用所消耗的总CPU时间(单位:微秒)
ELAPSED_TIMENUMBER归属于此顶级调用的所有递归调用所消耗的总时间(包括等待时间,单位:微秒)
BUFFER_GETSNUMBER归属于此顶级调用的所有递归调用所执行的总逻辑读次数
DISK_READSNUMBER归属于此顶级调用的所有递归调用所执行的总物理读次数
DIRECT_WRITESNUMBER归属于此顶级调用的所有递归调用所执行的总直接路径写次数(例如,直接路径加载,LOB操作)。
ROWS_PROCESSEDNUMBER归属于此顶级调用的所有递归调用所处理的总行数
COUNTNUMBER归属于此顶级调用的递归调用发生的总次数
CON_IDNUMBER所属容器的ID。在多租户环境中,标识该统计信息属于哪个PDB或CDB$ROOT。

4. 相关视图与基表

  • 相关动态性能视图

    • V$SQL: 这是最重要的关联视图V$SQL 中的 TOP_LEVEL_CALL_ID 字段指向 V$TOPLEVELCALL.TOP_LEVEL_CALL_ID,从而可以将一条递归SQL语句与其根源的顶级调用关联起来。V$SQL 中的 CALL_CLASS 字段也与本视图的 CALL_CLASS 对应。
    • V$SESSION: 当前会话正在执行的操作也有 TOP_LEVEL_CALL_ID,可用于实时诊断。
    • V$ACTIVE_SESSION_HISTORY (ASH) / DBA_HIST_ACTIVE_SESS_HISTORY: ASH数据中也包含 TOP_LEVEL_CALL_ID,允许对历史活动进行基于调用层次的分析。
    • V$SQLSTATS: 提供SQL的聚合统计,也包含 TOP_LEVEL_CALL_ID
  • 基表(Underlying Base Table)

    • **XKGLTOP∗∗:这是‘VKGLTOP**: 这是 `VKGLTOP:这是VTOPLEVELCALL` 所依赖的底层内存结构(基表)。它存储了顶级调用相关的统计信息。与其他X$表一样,它是内部的、未公开的,严禁直接查询
    • **XKGLCALLTREE∗∗:另一个相关的XKGLCALLTREE**: 另一个相关的XKGLCALLTREE:另一个相关的X表,可能用于维护调用树结构。
    • 视图定义查询:
      SELECT view_definition FROM v$fixed_view_definition WHERE view_name = 'GV$TOPLEVELCALL';
      

5. 底层详细原理

  1. 调用树(Call Tree)的构建

    • 当一个顶级调用(如 SELECT ...)进入数据库时,Oracle 会为其分配一个唯一的 TOP_LEVEL_CALL_ID
    • 在执行过程中,如果该调用需要触发递归SQL(例如,由于硬解析需要查询数据字典 SYS.TAB$),数据库内核会记录下这些递归SQL,并将它们的执行归属到同一个 TOP_LEVEL_CALL_ID 下。
    • 这样就形成了一棵以用户SQL为根、以各种递归SQL为枝叶的调用树
  2. 统计信息的聚合

    • 递归SQL在执行时,其资源消耗(CPU、I/O、逻辑读等)不仅会被记录到该递归SQL本身的游标中(在 V$SQL 中),还会被聚合到其所属的 TOP_LEVEL_CALL_ID 对应的统计记录中。
    • V$TOPLEVELCALL 视图本质上就是这些聚合后的统计信息的展示。它按 TOP_LEVEL_CALL_IDCALL_CLASS 分组,累加所有归属过来的递归调用的资源使用情况。
  3. 数据生命周期与开销

    • 这些统计信息存储在SGA中,实例重启后会被重置
    • 维护调用树和聚合统计信息会带来轻微的性能开销。因此,在某些极端性能敏感的场景下,Oracle可能不会对非常短暂或简单的调用进行深度跟踪。

6. 相关知识点介绍

  • 递归SQL的常见来源

    • 数据字典操作: 硬解析时查询表、列、权限等信息。
    • 空间管理: 执行DML时分配新区间(ALTER TABLE ... ALLOCATE EXTENT)、管理位图段。
    • 触发器: 触发器内部定义的SQL代码。
    • PL/SQL: 存储过程、函数、包中执行的SQL。
    • 索引维护CREATE INDEX 时排序和构建结构。
    • 审计: 如果启用了审计,写审计记录。
    • 高级功能: 如递归WITH查询(CTE)、某些分区操作等。
  • CALL_CLASS 的含义

    • RECURSIVE SPACE MGMT: 与段空间管理相关的递归调用,是性能问题的常见来源,特别是当表有很多扩展或使用ASSM管理时。
    • RECURSIVE SQL: 一般的递归SQL。
    • PL/SQL: 与PL/SQL引擎执行相关的调用。
  • 与等待事件的关系: 递归调用产生的等待事件(如 db file sequential read)也会被归属到顶级调用。在ASH报告中,可以按 TOP_LEVEL_CALL_ID 进行筛选,查看该调用树内发生的所有等待事件。

7. 常用查询 SQL

1. 查找消耗最多递归资源(如物理读)的顶级调用
这是最核心的查询,用于发现“隐藏”的性能消耗源。

SELECT top_level_call_id,
       top_level_call_name,
       call_class,
       disk_reads,
       round(cpu_time / 1000000, 2) as cpu_secs, -- 将微秒转换为秒
       round(elapsed_time / 1000000, 2) as elapsed_secs,
       buffer_gets,
       count
FROM v$toplevelcall
WHERE disk_reads > 0 OR cpu_time > 0 -- 筛选有活动的调用
ORDER BY disk_reads DESC; -- 按物理读排序,也可以按cpu_time或buffer_gets排序

2. 关联 V$SQL,查找导致大量递归调用的具体SQL文本
此查询将顶级调用ID与SQL文本关联起来。

SELECT t.top_level_call_id,
       t.top_level_call_name,
       t.call_class,
       s.sql_text,
       t.disk_reads,
       t.buffer_gets
FROM v$toplevelcall t
JOIN v$sql s ON t.top_level_call_id = s.top_level_call_id
WHERE s.top_level_call_id IS NOT NULL
AND t.disk_reads > 1000 -- 示例阈值
ORDER BY t.disk_reads DESC;

3. 分析特定SQL语句的递归调用明细
如果已知一个SQL的 SQL_ID,想查看它引发的递归调用详情。

SELECT s.sql_id,
       s.sql_text as recursive_sql_text,
       s.executions as recursive_execs,
       t.top_level_call_id,
       t.disk_reads,
       t.buffer_gets
FROM v$sql s
JOIN v$toplevelcall t ON s.top_level_call_id = t.top_level_call_id
WHERE s.sql_id = '&your_sql_id'; -- 替换为你要分析的SQL_ID

4. 按调用类型(CALL_CLASS)分组,查看系统总体递归开销

SELECT call_class,
       SUM(disk_reads) AS total_disk_reads,
       SUM(buffer_gets) AS total_buffer_gets,
       ROUND(SUM(cpu_time) / 1000000, 2) AS total_cpu_secs,
       SUM(count) AS total_recursive_calls
FROM v$toplevelcall
GROUP BY call_class
ORDER BY total_disk_reads DESC;

5. 在ASH数据中分析历史顶级调用(需要Diagnostic Pack)

SELECT h.top_level_call_id,
       t.top_level_call_name,
       t.call_class,
       COUNT(*) AS ash_sample_count,
       ROUND(COUNT(*) * 10 / 60, 2) AS approx_mins -- 假设ASH每10秒采样一次
FROM dba_hist_active_sess_history h
JOIN v$toplevelcall t ON h.top_level_call_id = t.top_level_call_id
WHERE h.sample_time > SYSDATE - 1/24 -- 查询最近1小时
AND h.top_level_call_id IS NOT NULL
GROUP BY h.top_level_call_id, t.top_level_call_name, t.call_class
ORDER BY ash_sample_count DESC;

总结

V$TOPLEVELCALL 动态性能视图提供了穿透表面,洞察根源的能力。它将数据库内部复杂的、自动执行的递归操作与最终的用户请求清晰地关联起来。

通过此视图,您可以:

  • 量化 一个用户操作的真实、总体的资源消耗,包括其所有“幕后”工作。
  • 定位 那些表面看起来简单、但实际上引发了大量内部活动的性能瓶颈语句。
  • 剖析 DDL、空间分配等操作的内部成本构成。
  • 深化 对Oracle数据库内部运作机制的理解。

它是性能优化专家工具箱中一件强大的武器,尤其适用于解决那些“简单SQL却执行缓慢”的疑难杂症。将它与 V$SQLASH 等视图结合使用,可以构建出极其强大的端到端性能诊断工作流。

欢迎关注我的公众号《IT小Chen

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值