查询在不同时间需要更长的时间有三个广泛的原因。要么因为系统处于不同类型的负载下而获得不同的性能,要么因为数据量变化而获得不同的性能,或者因为获得不同的查询计划而获得不同的性能。
不同的数据量
当您生成初始计时时,您使用的数据量是否与您的查询在实际运行时将遇到的数据量相似?如果您在本月的第一天测试一个查询,并且该查询正在获取当月的所有数据并执行一堆聚合,您会期望查询在一个月内变得越来越慢,因为它有处理越来越多的数据。或者,您可能有一个在月末处理之外快速运行的查询,因为它所依赖的各种临时表仅在月末填充。如果您在测试数据库中生成初始计时,您很可能会获得不同的性能,因为测试数据库通常具有实际生产数据的一小部分。
不同的系统负载
如果我在中午对我的数据仓库进行查询并运行它,那么很有可能数据仓库大部分时间都是空闲的,因此有很多资源可以让我处理查询。如果我是唯一的用户,我的查询可能会运行得非常快。另一方面,如果我尝试在每晚加载过程的中间运行完全相同的查询,我的查询将与许多其他进程竞争资源。即使我的查询必须完成完全相同的工作量,它也很容易花费很多倍的时钟时间来运行。如果您正在编写将在月底运行的报告,并且它们几乎在同一时间开始运行,那么它们完全有可能相互竞争有限的可用系统资源,而您的系统根本就不是。
不同的系统负载还可以包含诸如在任何时间点缓存的数据的差异之类的东西。如果我在 prod 中测试一个特定的查询并连续运行几次,我感兴趣的大部分数据很可能会被 Oracle、操作系统、SAN 缓存,等等。如果每次读取都来自一个缓存而不是需要磁盘读取,那么这可能会对性能产生巨大影响。如果您稍后在其他工作清除了您查询感兴趣的大部分块之后运行相同的查询,您最终可能会进行大量物理读取,而不是能够使用良好预热的缓存。那里'
不同的查询计划
随着时间的推移,您的查询计划也可能会发生变化,因为统计信息已更改(或未更改,具体取决于所讨论的统计信息)。通常,这表明 Oracle 找到了更有效的计划,或者您的数据量发生了变化,并且 Oracle 期望不同的计划对新的数据量更有效。但是,如果您给 Oracle 提供了错误的统计信息(例如,如果您的表在月末处理期间变得更大,但您在表几乎为空时收集统计信息),您可能会导致 Oracle 选择一个非常糟糕的查询计划。根据 Oracle 的版本,有多种方法可以强制 Oracle 使用相同的查询计划。如果您可以深入了解统计信息的问题所在,Oracle 可能会提供一种方法来为优化器提供更好的统计信息。
如果您查看 AWR/ASH 数据(如果您有适当的许可证)或 Statspace 数据(如果您的 DBA 已安装),您应该能够找出您的问题源自哪个阵营。您是否得到不同的查询计划对于不同的执行(您可能需要从初始基准中捕获查询计划并将其与当前计划进行比较,或者您可能需要增加 AWR 保留期以将查询计划保留几个月才能看到这一点)。您是否随着时间的推移执行相同数量的缓冲区获取,但获得的 I/O 等待数量却大不相同?您是否看到来自其他会话的大量资源争用?如果是这样,这可能表明问题是不同时间的不同负载。