Oracle SQL的时间你都清楚吗?

在 Oracle 数据库中,SQL 语句的执行性能是开发者和 DBA 关注的焦点。通过监控工具如 SQL Monitor ,OEM或 AWR 报告,我们可以获取各种时间指标,如 Duration Time、Elapsed Time、CPU Time 和 IO Time 等。这些指标帮助我们诊断瓶颈、优化查询,并理解客户端与数据库交互的影响。 但是你们知道这些时间分别代表什么吗?先看一个sql monitor的截图

一、Oracle SQL 执行时间指标概述 

Oracle 在执行 SQL 时,会记录多个时间维度,这些指标反映了从查询解析到结果返回的全过程。以下是核心指标的解释:

  1. Elapsed Time:
    • 定义:SQL 语句从开始执行到完成(包括所有子过程)的总实际时间,通常以秒为单位。
    • 包含内容:CPU 时间、IO 等待、网络延迟、锁等待等所有消耗。
    • 意义:这是用户感知的最直接性能指标。如果 Elapsed Time 过长,可能表示查询效率低或资源争用。
  2. CPU Time(CPU 时间):
    • 定义:SQL 执行过程中 CPU 实际使用的处理时间,不包括等待时间。
    • 包含内容:解析、优化、数据计算等 CPU 密集型操作。
    • 意义:如果 CPU Time 接近 Elapsed Time,说明查询是 CPU 绑定的(计算密集);反之,则可能是 IO 或其他等待主导。
    • 示例:图 中 CPU Time 为 5.86 秒,占 Elapsed Time 的绝大部分(约 81%),表明这个 SQL 主要是计算密集型,而非 IO 瓶颈。
  3. IO Time(IO 等待时间):
    • 定义:SQL 执行中等待磁盘或存储 IO 操作的时间,通常体现在 IO Waits(IO 等待秒数)中。
    • 包含内容:读取数据块(Buffer Gets)、物理读(Read Reqs 和 Read Bytes)等。
    • 意义:高 IO Time 往往表示数据访问效率低,可能需要优化索引、增加缓存或调整存储配置。
    • 示例:图中显示 IO Waits 为 1.36 秒,Read Reqs 1493 次,Read Bytes 886MB。这意味着 SQL 需要从磁盘读取大量数据(近 1GB),IO 等待贡献了部分 Elapsed Time。
  4. Duration Time(持续时间):
    • 定义:从客户端发起 SQL 到接收完整结果的总时间,包括数据库执行时间和客户端处理时间(如 Fetch 操作)。
    • 包含内容:Elapsed Time 加上客户端的网络传输、结果集缓冲和多次 Fetch 的开销。
    • 意义:Duration 通常大于或等于 Elapsed Time,因为它涵盖了端到端的体验。如果差距大,可能是客户端配置问题。
    • 示例:图中显示 Duration 为 27 秒,而 Elapsed Time 仅 7.22秒,相差近 20秒。这很可能由于多次 Fetch Calls 导致的客户端延迟,我们将在下一节详细讨论。

其他相关指标:

  • Fetch Calls(获取调用次数):客户端从数据库拉取结果集的次数。如果结果集大,而 Fetch Size 小,则需要多次调用,增加网络开销。
  • Buffer Gets(缓冲区获取):逻辑读次数,高值表示内存访问频繁。
  • 示例:图中显示 Fetch Calls 高达 111K,Buffer Gets 114K,这表示结果集很大,客户端分批拉取数据。

二、Fetch Calls 的影响

Java 默认 10 的陷阱与结果集输出问题在 Oracle SQL 执行中,Fetch Calls 是性能杀手之一,尤其在处理大结果集时。客户端(如 Java 应用)不会一次性拉取所有行,而是分批(Batch)获取,这由 Fetch Size 参数控制。

  1. Fetch Calls 的工作原理:
    • Oracle 数据库执行 SQL 后,结果集存储在游标中。客户端通过 OCI(Oracle Call Interface)或 JDBC 等接口调用 Fetch 来获取行。
    • 每次 Fetch 调用返回一批行(Fetch Size 指定的大小),直到结果集耗尽。
    • 高 Fetch Calls 表示多次网络往返,增加延迟,尤其在高延迟网络环境中。
  2. Java 默认 Fetch Size = 10 的问题:
    • 时间膨胀:每个 Fetch 都有网络开销、上下文切换和缓冲管理,导致 Duration >> Elapsed Time。
    • 资源消耗:数据库端需保持游标开放更久,消耗内存;客户端 CPU 和网络负载增加。
    • 结果集输出延迟:用户感知上,结果显示缓慢,甚至应用卡顿。
    • 在 JDBC 中,默认 Fetch Size 为 10,即每次只拉取 10 行。这适合小结果集,但对于大查询(如返回数万行),会导致成千上万的 Fetch Calls。
    • 影响:当然这个是一个极端的特例,这个sql的结果集超过110万,这是完全不合理的。 应该从业务端进行改善。
  3. 优化建议:
    • 将 JDBC Fetch Size 增大(如 setFetchSize(1000)),减少 Calls 次数。但需平衡内存使用,避免 OOM。
    • 使用批量处理或游标优化(如 PL/SQL 中的 BULK COLLECT)。
    • 如果是报告类查询,考虑分页或服务器端聚合,减少返回行数。
    • 监控:使用 V$SQL_MONITOR 或 AWR 报告追踪 Fetch 指标。

三、 SQL 时间问题的常见场景与解决方案

基于以上指标和截图,我们梳理一些典型的 SQL 时间问题:

  1. Elapsed Time 高,但 CPU Time 低:
    • 原因:IO 瓶颈(如 Image 0 的 1.36s IO Waits),或锁/队列等待。
    • 解决方案:添加索引、优化存储(ASM/SSD)、使用 materialized views。
  2. Duration >> Elapsed Time:
    • 原因:客户端 Fetch 开销大(如图中案例,27s vs 7s),网络延迟,或应用层处理慢。
    • 解决方案:增大 Fetch Size,优化网络,或使用阵列 Fetch(Array Fetch)。
  3. 高 Fetch Calls 导致的整体性能衰退:
    • 原因:结果集过大 + 小 Fetch Size(如 Java 默认 10)。
    • 解决方案:如上所述;另外,评估是否需要全结果集——或许用 COUNT(*) 先检查行数。
  4. 执行时间变异性:
    • 如 Image 1 的柱状图,不同执行从 19s 到 30s。
    • 原因:数据量变化、计划变更(CBO 优化器)、并发负载。
    • 解决方案:绑定变量、固定执行计划(Outline)、监控统计信息。
  5. 其他指标异常:
    • 高 Buffer Gets(114K):表示逻辑 IO 多,需优化 SQL(如避免全表扫描)。
    • 高 Read Bytes(980MB):物理 IO 重,考虑增加 SGA/PGA。

结语Oracle SQL 的时间指标如 Elapsed Time、CPU Time 和 Duration 提供了多维度视角,帮助我们从数据库到客户端全面优化性能。 只有了解每个参数的含义,才能更好的去理解sql去优化sql。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇湘秦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值