【问题标题】:How to log queries taking long time如何记录需要很长时间的查询
【发布时间】:2015-06-24 11:30:14
【问题描述】:

我在表 A 的 x 列中插入了一组大约 900 个查询。

然后我使用基本的 for 循环来循环并使用 Execute Immediate x ,问题是我想识别需要很长时间才能执行的查询,比如说 10 分钟以优化它们。 如果某些查询超过 10 分钟,是否有任何方法可以获取执行时间,我将其停止并将其 ID 记录在另一个表中并继续循环。

begin

   for query  in (select x from A)
   loop
      -- Some method to put a listner on the execution time
      execute immediate query.x;
   end loop
end; 

谢谢

【问题讨论】:

标签: sql oracle oracle11g sqlplus


【解决方案1】:

在最简单的“Heath Robinson”术语中,您可以将时间戳写入日志表“Query X start”和“Query x end”,以测量已用时间。曾经有一段时间您可以使用 tkprof,但如今大多数公司的安全策略规定开发人员无法访问服务器跟踪文件,因此该选项已失效。 Tkprof(使用 alter session set sql_trace = true)会告诉您解析时间、cpu 时间、经过时间、获取的行等。

您还可以为查询打开监控,以便在通过 Grid CControl/Enterprise Manager 查看时可以看到实时信息。详情见此链接:

http://www.oracle.com/technetwork/database/manageability/sqlmonitor-084401.html

您问题的第二部分很棘手。我不确定,或者更确切地说,我怀疑您是否可以在查询中设置超时。也许资源管理套件有一些东西,但我不确定。假设没有您将如何杀死正在运行的查询?你不能告诉 Oracle “杀死查询 x”,但你可以告诉它“杀死会话 x”,但这会杀死你的整个……会话。纯粹从技术挑战的角度考虑,而不是它是否优雅或实用,您可以将每个查询实现为一个作业并安排它运行,然后循环监控它的运行,如果它超过了你的时间限制,就杀死作业会话或终止作业。同样,我并不是说这就是你应该这样做的方式,但这是我尝试的一种方式,我需要这样做,并且我希望它会一路向上穿过一些弯曲的球。虽然这将是一个有趣的挑战.. 如果我有时间和意愿,我可能会去做。

【讨论】:

  • 运行和监视作业可能是使第二部分工作的唯一方法。 几乎有一种方法可以使用配置文件来做到这一点。创建一个配置文件,将每个查询限制为每次调用 10 分钟:create profile limit_cpu limit cpu_per_call 60000;。然后将其分配给用户:alter user some_user profile limit_cpu;。如果该用户的查询运行时间超过 10 分钟,则会失败并显示 ORA-02393: exceeded call limit on CPU usage。问题是它也会杀死整个会话,并且没有简单的方法来捕获该异常。
  • 假设我有 900 个查询,其中谈论 900 个工作,如果你能帮我举个例子,在 plsql 中调用 et 创建工作
  • 要创造就业机会,请查看docs.oracle.com/cd/B28359_01/server.111/b28310/…。这些查询是否必须按顺序运行?它们可以并行运行吗?
  • 是的,实际上我希望它们并行运行。执行顺序并不重要
  • 因此,您可以将查询分成组并并行运行这些组。 “查询”我认为您的意思是 SELECT 而不是 UPDATE/INSERT/DELETE,在这种情况下,您需要非常小心分组。每个组都以相同的方式执行 - 启动 DBMS_SCHEDULER 作业。让另一个 PLSQL 代码监视作业运行时间并杀死任何超出限制的内容。正如我所说,不优雅,可能会经历一些挑战。
【解决方案2】:

我对这种方法有一种不好的感觉:仅仅因为它的执行时间而识别一个“坏”的查询听起来很奇怪,并且可能会导致更多的错误。执行时间取决于许多因素,而这些因素可能与查询本身没有直接关系(例如数据集很小/很大,缓存配置),而且执行时间短(例如少于 10 分钟)并不一定意味着您查询很好。我宁愿根据他们的执行计划测试我的查询,当然,有一个好的测试数据集可用。

无论如何,Oracle 应该能够让您配置一些过期时间:在这种情况下,您必须在“立即执行”周围加上一个

BEGIN
   ...
EXCEPTION WHEN ... THEN ...;
END;

使用 EXCEPTION WHEN THEN 语句阻止超时。如果出现超时,您可以将该异常存储在某处以追踪您的“错误”查询。

【讨论】:

  • 根据我的经验,最终用户和利益相关者关心的唯一衡量标准是经过的时间。他们真的不在乎查询有多“昂贵”甚至有多“糟糕”,只要它很快就很棒。
  • 同意,腾格。但是,被“愚蠢”的最终用户和利益相关者包围不能成为阻止您成为更好的开发人员并区分“好”和“坏”代码的不在场证明。
猜你喜欢
  • 1970-01-01
  • 2016-02-02
  • 2018-01-09
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多