了解Oracle SQL Developer中的执行解释计划的结果

我试图优化一个查询,但不太理解从解释计划返回的一些信息。 任何人都可以告诉我的select和成本列的意义? 在OPTIONS列中,我只看到FULL字样。 在COST列中,我可以推断出一个较低的成本意味着一个更快的查询。 但是,成本价值究竟代表什么,什么是可接受的门槛?

EXPLAIN PLAN的输出是Oracle查询优化器的一个debugging输出。 COST是基于成本的优化器(CBO)的最终输出,其目的是select使用许多不同的可能计划中的哪一个来运行查询。 CBO计算每个计划的相对成本,然后select成本最低的计划。

(注:在某些情况下,CBO没有足够的时间来评估每一个可能的计划;在这种情况下,它只是select迄今为止成本最低的计划)

一般来说,缓慢查询的最大贡献者之一是为了服务查询而读取的行数(更确切地说,块),所以成本将部分基于优化者估计将需要的行数被阅读。

例如,假设您有以下查询:

SELECT emp_id FROM employees WHERE months_of_service = 6; 

months_of_service列对其有一个NOT NULL约束,并且在其上有一个普通索引。)

优化器在这里可以select两个基本计划:

  • 计划1:从“employees”表中读取所有行,检查谓词是否为true( months_of_service=6 )。
  • 计划2:读取months_of_service=6的索引(这会产生一组ROWID),然后根据返回的ROWID访问表。

让我们想象一下“雇员”表有100万(100万)行。 让我们进一步想象一下,months_of_service的值范围从1到12,并且由于某种原因而相当平均分配。

计划1涉及全面扫描的成本将是读取雇员表中所有行的成本,大约等于1,000,000; 但是由于Oracle经常能够使用多块读取来读取块,所以实际成本将会更低(取决于数据库的设置) – 例如让我们想象一下,多块读取计数是10 – 计算的成本全面扫描将是1000000/10; 总成本= 100,000。

涉及INDEX RANGE SCAN和ROWID查表的计划2的成本将是扫描索引的成本以及ROWID访问表的成本。 我不会去索引范围扫描如何计算成本,但我们可以想象索引范围扫描的成本是每行1个; 我们预计在12个案例中有1个匹配,所以索引扫描的成本是1,000,000 / 12 = 83,333; 加上访问表的成本(假设每个访问有1个块读取,我们不能在这里使用多块读取)= 83333; 总成本= 166,666。

如您所见,计划1(全面扫描)的成本低于计划2(索引扫描+通过rowid访问)的成本 – 这意味着CBO将selectFULL扫描。

如果优化器的假设是正确的,那么实际上计划1比计划2更有效率,这反映了FULL扫描总是“不好”的错误。

如果优化程序的目标是FIRST_ROWS(n)而不是ALL_ROWS,那么结果将会非常不同 – 在这种情况下,优化程序会偏好计划2,因为它往往会更快地返回前几行,代价是整个查询的效率较低。

CBO构build决策树,估算每个查询可用的每个可能执行path的成本。 成本由实例上设置的CPU_cost或I / O_cost参数设置。 CBO估计成本,尽可能使用查询将使用的表和索引的现有统计数据。 您不应该根据成本调整您的查询。 成本可以让你理解为什么优化器正在做什么。 没有成本,你可以找出为什么优化器select了它所做的计划。 降低成本并不意味着更快的查询。 有些情况是这样的,并且会出现这种情况。 成本是基于你的表格统计,如果他们错了,成本将是错误的。

在调整查询时,应该查看每个步骤的基数和行数。 他们有道理吗? 优化器假设正确的基数是多less? 行是否合理。 如果所提供的信息是错误的,那么优化器很可能没有正确的信息来做出正确的决定。 这可能是由于表和索引以及cpu-stats的陈旧或缺less统计信息。 调整查询以充分利用优化器时,最好具有更新的统计信息。 了解你的模式在调优时也很有帮助。 知道优化器何时select了一个非常糟糕的决策,并用小提示将其指向正确的path可以节省大量的时间。

以下是使用EXPLAIN PLAN和Oracle的参考资料: http : //download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm ),其中包含有关此处find的列的具体信息: http:/ /download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm#i18300

你提到的“FULL”表示查询正在进行全表扫描来查找你的数据。 这是可以的,在某些情况下,否则索引/查询写入不佳的指标。

一般来说,通过解释计划,您希望确保您的查询正在使用密钥,因此Oracle可以通过访问尽可能less的行数来查找您要查找的数据。 最终,你可以有一段时间才能得到你的桌子的架构。 如果成本仍然过高,则可能需要考虑调整架构的布局,使其更加以性能为基础。

在最近的Oracle版本中,COST代表了优化器期望查询所花费的时间,以单个块读取所需的时间量为单位来表示。

所以如果一个块读取需要2ms,并且成本表示为“250”,那么查询可能需要500ms才能完成。

优化器根据单块和多块读取的估计数量以及计划的CPU消耗来计算成本。 后者在通过在别人之前执行某些操作来尝试和避免高CPU成本操作来最小化成本方面是非常有用的。

这就提出了优化者如何知道操作需要多长时间的问题。 最近的Oracle版本允许“系统统计”的集合,这绝对不会与表或索引的统计信息混淆。 系统统计数据是对硬件性能的测量,主要是:

  1. 读取单个块需要多长时间
  2. 多块读取需要多长时间
  3. 多块读取有多大(通常由于表盘区的尺寸小于最大值以及其他原因而最大可能不同)。
  4. CPU性能

根据系统的运行环境,这些数字可能会有很大的差异,如果您愿意,可以存储“日间OLTP”操作和“夜间批量报告”操作以及“月末报告”的不同统计数据。

根据这些统计数据,可以在不同的操作环境中评估给定的查询执行计划的成本,这可能会促进在某些时候使用全表扫描或在其他情况下进行索引扫描。

成本并不完美,但优化器在每次发布时都会更好地进行自我监控,并且可以反馈实际成本与估计成本相比较,以便为将来做出更好的决策。 这也使得预测相当困难。

请注意,成本不一定是挂钟时间,因为并行查询操作消耗多个线程的总时间。

在Oracle的较早版本中,CPU操作的成本被忽略,单个和多个块读取的相对成本根据初始参数被有效地固定。

FULL可能指的是全表扫描,这意味着没有索引正在使用。 这通常表明有些事情是错误的,除非查询应该使用表中的所有行。

成本是指示不同负载,处理器,内存,磁盘,IO和高数量之和通常不好的数字。 移到计划的根部时,数字加起来,每个分支都应该被检查以确定瓶颈。

您可能还需要查询v $ sql和v $ session以获取有关SQL语句的统计信息,这将具有所有types的资源,时间安排和执行的详细指标。