为什么同一个查询需要花费不同的时间来运行?

时间:2013-06-05 19:25:23

标签: oracle

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

然后每个月,一些报告会持续数小时。这几个月之前几分钟都在运行的查询完全相同,突然间它们需要花费数小时才能运行。

我不时地重写我的程序而且对我来说这违背了自动化的目的。这里没人能帮助我。

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

我做了一些研究,它说在一个正确设置的数据库中,你甚至不需要使用提示,所以一切都应该在大约同一时间运行。

这是真的吗?或者每个人都有这个问题,每个人只要在他们跑步时重写他们的程序?

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

我的主要问题是,为什么同一个查询在不同的日子运行会花费不同的时间(差异,从几分钟到几小时)?

3 个答案:

答案 0 :(得分:4)

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

不同的数据量

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

不同的系统负载

如果我在一天中间对我的数据仓库进行查询并运行它,那么数据仓库很可能大部分处于空闲状态,因此有很多资源可以让我处理查询。如果我是唯一的用户,我的查询可能会很快运行。如果我尝试在夜间加载过程中尝试运行完全相同的查询,另一方面,我的查询将与许多其他进程竞争资源。即使我的查询必须完成相同数量的工作,它也可以轻松地运行更多的时钟时间。如果您正在编写将在月末运行的报告并且它们几乎在同一时间开始运行,那么它们完全有可能为了有限的系统资源而相互竞争,并且您的系统根本就不是t尺寸适合其需要处理的负载。

不同的系统负载也可以包含诸如在任何时间点缓存哪些数据的差异之类的事情。如果我在prod中测试一个特定的查询并且我连续运行了几次,那么很可能我感兴趣的大部分数据都将由Oracle,操作系统,SAN缓存,如果每次读取都来自其中一个缓存而不需要磁盘读取,那么性能会产生巨大差异。如果您在其他工作刷新了您的查询感兴趣的大多数块之后运行相同的查询,您最终可能会进行大量的物理读取而不是能够使用很好的预热缓存。关于这类事情通常没什么可做的 - 你可能能够缓存更多数据或安排需要类似数据的进程在相似时间运行,这样缓存效率更高,通常是昂贵和困难的要做。

不同的查询计划

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

如果您查看AWR / ASH数据(如果您有相应的许可证)或Statspace数据(如果您的DBA安装了该数据),您应该能够找出问题所在的阵营。你是否得到了针对不同执行的不同查询计划(您可能需要从初始基准测试中捕获查询计划并将其与当前计划进行比较,或者您可能需要提高AWR保留率以保留查询计划几个月才能看到此情况)。你是否正在做相同数量的缓冲区随着时间的推移而获得大量不同的I / O等待?您是否看到很多来自其他会话的资源争用?如果是这样,这可能表明问题在不同时间是不同的负载。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

是的,我正在使用相同的存档表,我将在未来几个月内使用它。当然,数据会发生变化,但这是一个相当稳定的上升,例如,如果一个表本月有10M行 - 下一个可能会获得100K行,下一个会增加200K,下一个会增加100K,依此类推。据我所知,没有剧烈的跳跃。而且我明白,如果今天查询花了2分钟,而下个月需要5分钟。但不是3小时。但是,谢谢你的想法,我将逐月开始计算表中的行数。 但问题是,人们如何编码来解释这个问题呢?假设有人使用可以随机获取大量数据的表,有没有办法编写查询以确保运行时间至少在球场?或者人们只是忍受这样一个事实:他们的报告将在任何月份运行10-20小时。

不同的系统负载 如果我拿...处理。

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

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

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

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

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