5

我有这个问题已经持续了几个月。我在工作中自动生成报告,我们使用 oracle。我写了一个程序,计时,它在几分钟内运行。然后我将其设置为每月运行。

然后每个月,一些报告都会运行数小时。之前几个月都在几分钟内运行的所有查询都是相同的查询,突然之间它们需要几个小时才能运行。

我最终会时不时地重写我的程序,对我来说,这违背了自动化的目的。这里没有人能帮助我。

我究竟做错了什么?如何确保我的查询始终花费相同的时间来运行。

我做了一些研究,它说在具有正确统计信息的正确设置数据库中,您甚至不必使用提示,一切都应该始终在大约同一时间运行。

这是真的?还是每个人都有这个问题,每个人都只是在运行时重写他们的程序?

抱歉,有 100 个问题,我对此感到非常沮丧。

我的主要问题是,为什么相同的查询需要不同的时间(从几分钟到几小时的巨大差异)在不同的日子运行?

4

3 回答 3

5

查询在不同时间需要更长的时间有三个广泛的原因。要么因为系统处于不同类型的负载下而获得不同的性能,要么因为数据量变化而获得不同的性能,或者因为获得不同的查询计划而获得不同的性能。

不同的数据量

当您生成初始计时时,您使用的数据量是否与您的查询在实际运行时将遇到的数据量相似?如果您在本月的第一天测试一个查询,并且该查询正在获取当月的所有数据并执行一堆聚合,您会期望查询在一个月内变得越来越慢,因为它有处理越来越多的数据。或者,您可能有一个在月末处理之外快速运行的查询,因为它所依赖的各种临时表仅在月末填充。如果您在测试数据库中生成初始计时,您很可能会获得不同的性能,因为测试数据库通常具有实际生产数据的一小部分。

不同的系统负载

如果我在中午对我的数据仓库进行查询并运行它,那么很有可能数据仓库大部分时间都是空闲的,因此有很多资源可以让我处理查询。如果我是唯一的用户,我的查询可能会运行得非常快。另一方面,如果我尝试在每晚加载过程的中间运行完全相同的查询,我的查询将与许多其他进程竞争资源。即使我的查询必须完成完全相同的工作量,它也很容易花费很多倍的时钟时间来运行。如果您正在编写将在月底运行的报告,并且它们几乎在同一时间开始运行,那么它们完全有可能相互竞争有限的可用系统资源,而您的系统根本就不是。

不同的系统负载还可以包含诸如在任何时间点缓存的数据的差异之类的东西。如果我在 prod 中测试一个特定的查询并连续运行几次,我感兴趣的大部分数据很可能会被 Oracle、操作系统、SAN 缓存,等等。如果每次读取都来自一个缓存而不是需要磁盘读取,那么这可能会对性能产生巨大影响。如果您稍后在其他工作清除了您查询感兴趣的大部分块之后运行相同的查询,您最终可能会进行大量物理读取,而不是能够使用良好预热的缓存。那里'

不同的查询计划

随着时间的推移,您的查询计划也可能会发生变化,因为统计信息已更改(或未更改,具体取决于所讨论的统计信息)。通常,这表明 Oracle 找到了更有效的计划,或者您的数据量发生了变化,并且 Oracle 期望不同的计划对新的数据量更有效。但是,如果您给 Oracle 提供了错误的统计信息(例如,如果您的表在月末处理期间变得更大,但您在表几乎为空时收集统计信息),您可能会导致 Oracle 选择一个非常糟糕的查询计划。根据 Oracle 的版本,有多种方法可以强制 Oracle 使用相同的查询计划。如果您可以深入了解统计信息的问题所在,Oracle 可能会提供一种方法来为优化器提供更好的统计信息。

如果您查看 AWR/ASH 数据(如果您有适当的许可证)或 Statspace 数据(如果您的 DBA 已安装),您应该能够找出您的问题源自哪个阵营。您是否得到不同的查询计划对于不同的执行(您可能需要从初始基准中捕获查询计划并将其与当前计划进行比较,或者您可能需要增加 AWR 保留期以将查询计划保留几个月才能看到这一点)。您是否随着时间的推移执行相同数量的缓冲区获取,但获得的 I/O 等待数量却大不相同?您是否看到来自其他会话的大量资源争用?如果是这样,这可能表明问题是不同时间的不同负载。

于 2013-06-05T20:21:45.627 回答
0

一种可能性是您的执行计划被缓存了,因此重新运行查询需要很短的时间,但是当计划不再被缓存时(例如在数据库重新启动之后),它可能需要更长的时间。

很久以前,我在 Oracle 上遇到过类似的问题,其中一个非常复杂的报表查询针对大量数据运行,并且在数据库重新启动后第一次运行它需要几个小时才能完成,但在那之后它在几分钟内完成。

于 2013-06-05T19:31:25.397 回答
0

这不是答案,这是对 Justin Cave 的回复,我无法在评论中以任何可读的方式对其进行格式化。

不同的数据量当......数据。

是的,我正在使用相同的存档表,然后我会在接下来的几个月中使用这些存档表。当然,数据会发生变化,但上升的幅度相当一致,例如,如果一个表本月有 1000 万行——它可能会在下一个增加 100K 行,下一个增加 200K,下一个增加 100K 等等。据我所知,没有剧烈的跳跃。如果今天查询需要 2 分钟,而下个月需要 5 分钟,我会理解。但不是 3 小时。但是,感谢您的想法,我也将开始逐月计算表中的行数。但问题是,人们如何编码来解决这个问题?假设有人使用会随机获取大量数据的表,有没有办法编写查询以确保运行时间至少在球场内?还是人们只是忍受他们的报告在任何一个月都会运行 10-20 小时的事实。

不同的系统负载如果我采取...。来处理。

* *不,我在不同的日期和时间运行我的查询,但我有日期和时间的日志,所以我会看看我是否能找到一个模式。

不同的系统负载……很难做到。

所以你是说我在设计报告时可能会很快,因为我以前在我的电脑上运行的东西?此外,缓存是存储在我的计算机上还是存储在我的登录名下的数据库中还是在哪里?**

不同的查询计划随着时间的推移,您的查询计划……在不同的时间有不同的负载。

谢谢你的解释,你给了我足够的开始挖掘。

于 2013-06-05T21:16:09.090 回答