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

Oracle 为什么同一个查询需要不同的运行时间?,oracle,Oracle,我的问题已经持续了好几个月了。我在工作中自动生成报告,我们使用oracle。我写了一个程序,计时,几分钟就可以运行了。然后我将其设置为每月运行 然后每个月,一些报告会运行数小时。这和几个月前在几分钟内运行的查询是一样的,但突然之间,它们需要几个小时才能运行 最后,我时不时地重写我的程序,对我来说,这违背了自动化的目的。这里没有人能帮我 我做错了什么?我如何确保我的查询始终需要相同的运行时间 我做了一些研究,它说,在一个正确设置的数据库中,有正确的统计数据,你甚至不必使用提示,所有的东西都应该在大

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

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

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

我做错了什么?我如何确保我的查询始终需要相同的运行时间

我做了一些研究,它说,在一个正确设置的数据库中,有正确的统计数据,你甚至不必使用提示,所有的东西都应该在大约相同的时间运行

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

抱歉问了100个问题,我真的很沮丧


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

一种可能性是,您的执行计划已缓存,因此重新运行查询所需的时间较短,但当不再缓存该计划时(如数据库重新启动后)这可能需要更长的时间


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

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

不同的数据量

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

不同的系统负载

如果我在中午对数据仓库执行查询并运行它,那么数据仓库很有可能大部分时间处于空闲状态,因此有大量资源可供我处理查询。如果我是唯一的用户,我的查询可能运行得很快。另一方面,如果我试图在夜间加载过程中运行完全相同的查询,我的查询将与许多其他进程竞争资源。即使我的查询必须完成完全相同的工作量,运行它也很容易需要更多的时钟时间。如果您正在编写将在月末运行的报告,并且它们几乎同时启动,则完全可能它们都在为有限的可用系统资源而相互竞争,并且您的系统的大小根本无法满足其需要处理的负载

不同的系统负载还可能包含诸如在任何时间点缓存的数据的差异之类的内容。如果我在prod中测试一个特定的查询,并连续运行几次,我感兴趣的大多数数据很可能会被Oracle、操作系统、SAN等缓存。如果每次读取都来自其中一个缓存,而不需要磁盘读取,那么性能会有很大的不同。如果在其他工作清除了查询所感兴趣的大部分块之后运行同一查询,那么最终可能会进行大量物理读取,而无法使用经过良好预热的缓存。对于这类事情,通常没有什么可以做的——您可以缓存更多的数据,或者安排需要类似数据的进程在相似的时间运行,这样缓存效率更高,但这通常是昂贵且难以做到的

不同的查询计划

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

如果查看AWR/ASH数据(如果您有相应的许可证)或Statspace数据(如果您的DBA安装了该数据),您应该能够找出问题的根源。您是否为不同的执行获得了不同的查询计划(您可能需要从初始基准捕获一个查询计划,并将其与当前计划进行比较,或者