为什么相同的查询需要不同的时间来运行?

lal*_*hka 6 oracle

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

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

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

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

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

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

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

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

Jus*_*ave 5

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

不同的数据量

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

不同的系统负载

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

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

不同的查询计划

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

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