如何记录花费很长时间的查询

How to log queries taking long time

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

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

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; 

谢谢

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

无论如何,Oracle 应该能够让您配置一些过期时间:在那种情况下,您必须用

包围您的 "execute immediate"
BEGIN
   ...
EXCEPTION WHEN ... THEN ...;
END;

块使用 EXCEPTION WHEN THEN 语句来捕获超时。如果出现超时,您将该异常存储在某处以跟踪您的 "bad" 查询。

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

您还可以为查询打开监控,以便在通过网格 COntrol/Enterprise 管理器查看时,您可以看到实时信息。有关详细信息,请参阅此 link:

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

你问题的第二部分很棘手。我不确定,或者更确切地说,我怀疑您是否可以为查询设置超时。也许资源管理套件有一些东西,但我不确定。假设没有您将如何终止 运行ning 的查询?您不能告诉 Oracle "Kill query x",但可以告诉它 "kill session x",但这会终止您的整个 ... 会话。纯粹从技术挑战的角度考虑,而不是优雅或实用,您可以将每个查询作为一个作业来实现,并将其调度到 运行,然后循环监视其 运行ning,如果它超过了您的时间限制,终止工作会话或终止工作。再一次,我并不是说你应该这样做,但这是我尝试的一种方式,我需要这样做,我希望它能沿途穿过一些弯曲的球。这将是一个有趣的挑战..如果我有时间和意愿的话,我可能会去做。