【问题标题】:how to change oracle explain plan for sql query manually [duplicate]如何手动更改sql查询的oracle解释计划[重复]
【发布时间】:2014-09-25 10:05:51
【问题描述】:

我有一个 oracle sql 查询,它附有访问计划。如何在不更改 sql 查询的情况下更改访问计划。我认为 oracle 有存储 sql id 和 plan id 的数据库表,将 plan id 更新为新的 plan id 将强制 sql 查询使用不同的解释计划。

我使用的是 Oracle 10,在这种情况下,我不想触及现有的查询。我将编写另一个带有提示的查询并创建所需的解释计划。现在我将为解释计划使用新标记并将其附加到原始 sql id。这是如何做到这一点的逻辑,但我不知道所有表需要更新才能实现这一点。第一步:SQLI_D1 -> PLAN_ID1;第二步:SQL_ID2 -> PLAN_ID2;第三步:SQL_ID1 -> PLAN_ID2

【问题讨论】:

  • 您为什么要这样做 - 因为您认为 Oracle 选择了次优计划? Oracle 是否拥有制定合理计划所需的所有信息——尤其是统计数据是否最新?或者,如果您使用 10g,您是否可能遭受绑定变量偷看? (这在 11g 上不是问题)。您可以向优化器提供提示,但这会更改语句,并且通常有点难以隐藏潜在问题。

标签: oracle


【解决方案1】:

答案太多了,因为你的问题太宽泛了。而且你甚至没有提到数据库版本。

你说:

将计划 ID 更新为新计划 ID 将强制使用 sql 查询 不同的解释计划。

没有。 PLAN_HASH_VALUE 由 Oracle 分配。它是将EXECUTION PLAN 与相应的SQL_ID 相关联的标记。如果您想强制OPTIMIZER 采用您选择的不同执行计划,您可以在查询中使用HINTS

如果您使用stored outlines 等(也称为PLAN STABILITY固定或保留了 SQL 的执行计划,那么您需要将其删除,以便 Oracle 能够在下一次执行中找到合适的执行计划。然后,如果需要,您可以按照您的想法稳定更好的计划。

【讨论】:

  • 我使用的是 Oracle 10,在这种情况下,我不想触及现有的查询。我将编写另一个带有提示的查询并创建所需的解释计划。现在我将为解释计划使用新标记并将其附加到原始 sql id。这是如何做到这一点的逻辑,但我不知道所有表需要更新才能实现这一点。第一步:SQLI_D1 -> PLAN_ID1;第二步:SQL_ID2 -> PLAN_ID2;第 3 步:SQL_ID1 -> PLAN_ID2
【解决方案2】:

解释计划取决于它的查询和统计数据。例如,如果表中只有一条记录,oracle 不会使用索引,但如果表中有很多记录并且您只提取其中的几条记录,它将使用索引。所以你需要尽可能多地收集统计数据。

但我不明白您要强制 oracle 重新计算解释计划的意图,Oracle 知道如何根据您提供的统计信息访问您的表。不要使用 INDEX 之类的提示和其他告诉 oracle 如何访问表的提示。您可以给 oracle 一个提示,告诉 oracle 您只需要前 5 行,oracle 会尽快将它们返回给您。

【讨论】:

  • >oracle won't use an index if there is only one record in the table .... 你确定吗? 我可以告诉你,Oracle 将使用只有一行的索引表。
  • @LalitKumarB - 如果它的选择性意味着执行单独的索引和表提取会更昂贵,它通常不会使用索引。当您只能使用一个时,为什么要进行两批 I/O?单行只是一个极端的例子。 (我忘记了首先达到索引效率更高的阈值,但我曾经使用 10-15% 作为经验法则)。 zaratustra 的演示也可以使用明确的gather_schema_stats()
  • @Alex,作为一个 ROT,我把它保持得更低,~ 5-10%。但是,这取决于很多因素。我指的是 zaratustra 的声明,它不能完全是唯一的情况。没有关于表中行数的索引扫描的经验法则。
  • @AlexPoole 感谢您的澄清。我用这个极端的例子告诉 OP,oracle 知道自己要做什么。
猜你喜欢
  • 2011-02-16
  • 2012-12-16
  • 2011-05-21
  • 2015-07-16
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 2013-02-05
相关资源
最近更新 更多