我的部门最近被我们的IT部门(很好地)训斥,因为我们的查询实际上有可能破坏数据库的稳定性和/或使数据库崩溃,因此以非常高的成本运行查询。我们都不是DBA的;只是研究人员对数据库进行编写和执行查询,而且我可能是唯一一个在谴责之前查看过解释计划的人。
我们被告知超过100的查询成本应该是非常罕见的,并且永远不应该运行成本超过1000的查询。我遇到的问题是成本似乎与执行时间无关,而且在尝试优化查询时我会失去工作效率。
作为一个例子,我有一个查询,在5秒内执行,成本为10844.我重写了查询以使用包含我需要的大部分信息的视图,并将成本降低到109,但是检索相同结果的新查询需要40秒才能运行。我在这里找到了一个问题可能的解释:
Measuring Query Performance : "Execution Plan Query Cost" vs "Time Taken"
这个问题让我得到了并行性的暗示。我尝试在成本10884查询中使用/*+ no_parallel*/
,但成本没有改变,执行时间也没有改变,所以我不确定并行性是更快执行时间但成本更高的解释。然后,我尝试使用/*+ parallel(n)*/
提示,发现n
的值越高,查询的成本就越低。在成本为10844查询的情况下,我发现/*+ parallel(140)*/
将成本降低到97,执行时间略有增加。
这似乎是满足我们IT部门提出的要求的理想“欺骗”,但后来我读到了这个:
这篇文章包含这句话:
并行执行可以使单个操作利用所有系统资源。
所以,我的问题是:
即使我降低了成本,我实际上是通过使用具有高度并行性的/*+ parallel(n)*/
提示给服务器资源施加更多压力吗?
假设没有并行性,执行速度是否比成本更好地衡量所使用的资源?
答案 0 :(得分:6)
你的DBA给你的规则并没有多大意义。担心为查询报告的成本非常低效。首先,您不能直接比较两个不同查询的成本 - 一个成本为数百万的查询可能运行得非常快并且消耗很少的系统资源另一个具有数百个成本的查询可能会运行几个小时并带来服务器跪了下来。其次,成本是一种估计。如果优化器对成本进行了准确估计,则强烈暗示它已经提出了最佳查询计划,这意味着您不太可能在使用时修改查询以返回相同的结果资源减少。如果优化程序对成本进行了不准确的估计,那么强烈暗示它已经提出了一个糟糕的查询计划,在这种情况下,报告的成本与您提出的任何有用指标没有任何关系。大多数情况下,您尝试优化的查询是优化程序生成错误查询计划的查询,因为它错误地估算了各个步骤的成本。
通过使用可能或可能不会实际更改查询计划的提示来欺骗优化器(例如,取决于如何配置并行性)不太可能解决问题 - 它更可能导致优化程序的估计不太准确,并且更有可能选择一个消耗远远超过其需要的资源的查询计划。例如,具有高度并行性的parallel
提示将告诉Oracle大幅降低全表扫描的成本,这使得优化器更有可能通过索引扫描选择它。这很少是您的DBA想要看到的东西。
如果您正在寻找一个告诉您查询计划是否合理的指标,我会使用逻辑I / O的数量。逻辑I / O与实际查询性能以及查询消耗的资源量相关。查看执行时间可能会有问题,因为它会根据正在缓存的数据而显着变化(这就是为什么查询通常在第二次执行时运行得更快),而逻辑I / O不会根据需要进行更改关于缓存中的数据。它还允许您根据查询处理更改所需的行数来扩展您的期望。例如,如果您正在编写需要聚合来自100万行的数据的查询,那么应该比需要从没有聚合的表返回100行数据的查询消耗更多的资源。如果您正在查看逻辑I / O,则可以轻松地将期望值扩展到问题的大小,以确定查询的实际效率。
在Christian Antognini" Troubleshooting Oracle Performance" (第450页),例如,他给出了一个非常合理的经验法则
具有不同数据模型的不同系统可能值得稍微调整一下桶,但这些可能是很好的起点。
我的猜测是,如果您是非开发人员的研究人员,您可能正在运行需要聚合或获取相对较大数据集的查询,至少与应用程序开发人员通常编写的那些相比较。如果您要扫描一百万行数据以生成一些聚合结果,那么您的查询自然会比查询正在读取或写入少量行的应用程序开发人员消耗更多资源。您可能正在编写从每行逻辑I / O角度来看同样有效的查询,您可能正在查看更多行。
如果您正在对实时生产数据库运行查询,则可能处于开始分离工作负载的情况。大多数组织都会针对实时数据库运行报告查询开始为生产系统创建问题。这类问题的一个常见解决方案是创建一个单独的报告数据库,该数据库从生产系统(通过夜间快照或正在进行的复制过程)提供,报告查询可以在不影响生产应用程序的情况下运行。另一个常见的解决方案是使用Oracle Resource Manager之类的东西来限制一组用户(在本例中为报告开发人员)可用的资源量,以便最大限度地减少对较高优先级用户的影响(在这种情况下,生产用户)系统)。