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

Kev*_*ock 64 oracle oracle-sqldeveloper sql-execution-plan

我正在尝试优化查询,但不太了解解释计划返回的一些信息.谁能告诉我OPTIONS和COST专栏的重要性?在OPTIONS列中,我只看到单词FULL.在COST专栏中,我可以推断出较低的成本意味着更快的查询.但是,成本价值究竟代表什么,可接受的阈值是多少?

Jef*_*emp 104

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

(注意:在某些情况下,CBO没有足够的时间来评估每个可能的计划;在这些情况下,它只选择到目前为止发现的最低成本的计划)

通常,慢查询的最大贡献者之一是为查询提供服务所读取的行数(更准确地说是块),因此成本将部分取决于优化程序估计需要的行数被阅读.

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

SELECT emp_id FROM employees WHERE months_of_service = 6;
Run Code Online (Sandbox Code Playgroud)

(该months_of_service列上有一个NOT NULL约束,上面有一个普通的索引.)

优化器可以在此处选择两个基本计划:

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

让我们假设"员工"表有1,000,000(100万)行.让我们进一步想象,months_of_service的值范围从1到12,并且由于某种原因分布相当均匀.

计划1的成本(涉及全面扫描)将是读取员工表中所有行的成本,大约等于1,000,000; 但由于Oracle通常能够使用多块读取来读取块,因此实际成本会降低(取决于数据库的设置方式) - 例如,让我们假设多块读取计数为10 - 计算出的成本全扫描将是1,000,000/10; 总成本= 100,000.

计划2的成本(包括INDEX RANGE SCAN和ROWID的表查找)将是扫描索引的成本,加上ROWID访问表的成本.我不会深入研究索引范围扫描的成本,但让我们假设索引范围扫描的成本是每行1; 我们希望在12个案例中找到一个匹配,因此索引扫描的成本是1,000,000/12 = 83,333; 加上访问表的成本(假设每次访问读取1个块,我们不能在这里使用多块读取)= 83,333; 总成本= 166,666.

如您所见,计划1(完全扫描)的成本低于计划2(索引扫描+ rowid访问)的成本 - 这意味着CBO将选择完整扫描.

如果优化器在这里做出的假设是正确的,那么实际上计划1将比计划2更可取并且更有效 - 这反驳了完全扫描"总是坏"的神话.

如果优化器目标是FIRST_ROWS(n)而不是ALL_ROWS,结果会大不相同 - 在这种情况下,优化器会支持计划2,因为它通常会更快地返回前几行,但代价是整个查询效率较低.


小智 7

CBO构建决策树,估计每个查询可用的每个可能执行路径的成本.成本由实例上设置的CPU_cost或I/O_cost参数设置.CBO会根据查询将使用的表和索引的现有统计信息来估算成本.您不应该仅根据成本调整查询.成本允许您了解优化程序正在执行的操作.没有成本,你可以弄清楚为什么优化器选择它做的计划.降低成本并不意味着更快的查询.在某些情况下,这是真的,并且会出现这种情况.成本取决于您的表统计数据,如果错误,则成本会出错.

在调整查询时,您应该查看每个步骤的基数和行数.他们有道理吗?优化器假设的基数是否正确?行返回是否合理.如果存在的信息是错误的,那么优化器很可能没有正确决策所需的适当信息.这可能是由于表和索引以及cpu-stats的陈旧或缺失统计信息.在调优查询以最大限度地利用优化程序时,最好更新统计信息.在调优时,了解您的架构也非常有用.知道优化器何时选择了一个非常糟糕的决策,并用一个小提示将其指向正确的路径可以节省大量时间.


dro*_*owe 6

以下是使用EXPLAIN PLAN with 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可以通过访问尽可能少的行来查找您正在查找的数据.最终,您有时只能使用表格的架构.如果成本仍然太高,您可能必须考虑调整架构的布局以使其更具基于性能的能力.