我正在尝试优化查询,但不太了解Explain Plan返回的一些信息。谁能告诉我OPTIONS和COST列的重要性?在“选项”列中,我仅看到“已满”一词。在COST列中,我可以推断出较低的成本意味着更快的查询。但是成本值究竟代表什么,可接受的阈值是多少?
Answers:
EXPLAIN PLAN的输出是Oracle查询优化器的调试输出。COST是基于成本的优化器(CBO)的最终输出,其目的是选择应使用许多不同的可能计划中的哪一个来运行查询。CBO计算每个计划的相对成本,然后选择成本最低的计划。
(注意:在某些情况下,CBO没有足够的时间来评估每个可能的计划;在这些情况下,它只是选择了迄今为止发现的成本最低的计划)
通常,对慢速查询的最大促成因素之一是为查询服务而读取的行数(更精确地说,是块),因此成本将部分基于优化器估计所需的行数。被阅读。
例如,假设您有以下查询:
SELECT emp_id FROM employees WHERE months_of_service = 6;
( months_of_service
列具有NOT NULL约束,并且具有普通索引。)
优化器可以在此处选择两个基本计划:
months_of_service=6
)。months_of_service=6
(这将导致一组ROWID),然后根据返回的ROWID访问表。假设“员工”表有1,000,000(100万)行。让我们进一步想象一下,months_of_service的值的范围是1到12,并且由于某种原因它们分布相当均匀。
计划1的成本(包括全面扫描)将是读取employee表中所有行的成本,大约等于1,000,000;但是由于Oracle通常能够使用多块读取来读取块,因此实际成本会更低(取决于数据库的设置方式)-例如,假设多块读取计数为10-计算得出的成本为完整扫描将为1,000,000 / 10; 总成本= 100,000。
计划2的费用包括INDEX RANGE SCAN和按ROWID查找表)将是扫描索引的成本,加上按ROWID访问表的成本。我将不讨论索引范围扫描的成本,但让我们想象一下索引范围扫描的成本是每行1。我们希望在12个案例中找到1个匹配项,因此索引扫描的费用为1,000,000 / 12 = 83,333;加上访问表的成本(假设每次访问读取1个块,在这里我们不能使用多块读取)= 83,333;总成本= 166,666。
如您所见,计划1(完全扫描)的成本比计划2(索引扫描+按行ID访问)的成本低-这意味着CBO将选择完全扫描。
如果优化器在这里所做的假设是正确的,那么实际上计划1将比计划2更可取,效率更高-这证明了FULL扫描“总是不好”的说法。
如果优化程序的目标是FIRST_ROWS(n)而不是ALL_ROWS,则结果将大不相同-在这种情况下,优化程序将青睐Plan 2,因为它通常会更快地返回前几行,但会降低整个查询的效率。
CBO构建一个决策树,以估计每个查询可用的每个可能执行路径的成本。成本由实例上设置的CPU_cost或I / O_cost参数设置。而且,CBO会根据查询将使用的表和索引的现有统计信息,尽可能地估算成本。您不应仅根据成本来调整查询。成本使您能够了解优化器为何要执行其工作。没有成本,您可以弄清楚为什么优化器选择了它执行的计划。较低的成本并不意味着查询会更快。在某些情况下,这是正确的,在某些情况下,这是错误的。费用基于您的表格统计信息,如果错误,则费用将是错误的。
调整查询时,应查看基数和每个步骤的行数。他们有道理吗?优化程序假设的基数正确吗?返回的行是否合理?如果提供的信息有误,则优化器很可能没有正确决策所需的正确信息。这可能是由于表和索引以及cpu-stats的统计数据过时或丢失。调整查询以充分利用优化程序时最好更新统计信息。进行调整时,了解您的架构也很有帮助。知道优化器何时选择了一个非常糟糕的决定,并以很小的提示将其指向正确的路径,可以节省大量时间。
这是将EXPLAIN PLAN与Oracle一起使用的参考:http : //download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm),有关在此处找到的列的具体信息:http:/ /download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm#i18300
您提到的“ FULL”向我表明查询正在执行全表扫描以查找您的数据。没关系,在某些情况下,否则表明索引编制/查询编写不佳。
通常,使用解释计划时,您要确保查询使用键,因此Oracle可以通过访问尽可能少的行数来查找所需的数据。最终,您有时只能了解表的架构。如果成本仍然太高,则可能必须考虑调整架构的布局以使其更加基于性能。
在最新的Oracle版本中,COST表示优化器希望查询执行的时间量,以单块读取所需时间量的单位表示。
因此,如果单个块读取花费2毫秒,并且开销表示为“ 250”,则查询可能需要500毫秒才能完成。
优化程序根据估计的单块和多块读取数以及计划的CPU消耗来计算成本。通过在执行某些操作之前先执行某些操作来尝试避免CPU成本过高的操作,后者对于降低成本非常有用。
这就提出了一个问题,即优化器如何知道需要多长时间。Oracle的最新版本允许收集“系统统计信息”,绝对不要将它们与表或索引的统计信息混淆。系统统计数据是对硬件性能的度量,最重要的是:
这些数字可能会根据系统的操作环境而有很大差异,并且如果需要,可以为“白天OLTP”操作和“夜间批处理报告”操作以及“月末报告”存储不同的统计信息集。
有了这些统计信息集,就可以评估给定查询执行计划在不同操作环境中的成本,这可能会促进在某些时候使用全表扫描或在其他时候使用索引扫描。
成本不是完美的,但是优化器在每次发布时都具有更好的自我监控能力,并且可以将实际成本与估计成本进行比较,以做出更好的未来决策。这也使预测变得更加困难。
请注意,代价不一定是挂钟时间,因为并行查询操作会占用多个线程的总时间。
在旧版本的Oracle中,CPU操作成本被忽略,并且根据初始化参数有效地固定了单块读取和多块读取的相对成本。