如何手动更改oracle sql查询解释计划

如何手动更改oracle sql查询解释计划,oracle,Oracle,我有一个oracle sql查询,它附带了访问计划。如何在不更改sql查询的情况下更改访问计划。我认为oracle有存储sql id和计划id的数据库表,将计划id更新为新的计划id将强制sql查询使用不同的计划 我使用的是Oracle 10,在这种情况下,我不想触及现有的查询。我将编写另一个带有提示的查询,并创建所需的解释计划。现在,我将为解释计划使用新的标记,并将其附加到原始的sql id。这是如何做到这一点的逻辑,但我不知道需要更新哪些表来实现这一点。步骤1:SQLI\U D1->PLAN

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


我使用的是Oracle 10,在这种情况下,我不想触及现有的查询。我将编写另一个带有提示的查询,并创建所需的解释计划。现在,我将为解释计划使用新的标记,并将其附加到原始的sql id。这是如何做到这一点的逻辑,但我不知道需要更新哪些表来实现这一点。步骤1:SQLI\U D1->PLAN\U ID1;步骤2:SQL\u ID2->PLAN\u ID2;步骤3:SQL\u ID1->PLAN\u ID2

答案太多了,因为你的问题太宽泛了。你甚至没有提到DB版本

你说:

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

否。
计划散列值
由Oracle分配。它是一个标记,用于将
执行计划
与相应的
SQL\u ID
关联。如果要强制
优化器
采用您选择的不同执行计划,可以在查询中使用
提示


如果您使用
存储的大纲
等(也称为
计划稳定性
)固定或保留了SQL的执行计划,则需要将其删除,以便Oracle能够在下次执行中找到适当的执行计划。然后,如果需要,您可以按照自己的想法稳定更好的计划。

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


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

为什么要这样做?因为您认为oracle选择了次优计划?Oracle是否拥有制定合理计划所需的所有信息?尤其是统计数据是否最新?或者,如果您使用的是10g,您是否正在遭受绑定变量偷看的痛苦?(这在11g上不是什么问题)。您可以向优化器提供提示,但这会改变语句,并且隐藏潜在问题通常有点麻烦。>
如果表中只有一条记录,oracle不会使用索引。
。。。。你确定吗?我可以向您展示Oracle将只使用表中一行的索引。@LalitKumarB-如果索引的选择性意味着单独获取索引和表的成本更高,它通常不会使用索引。当您只能使用一个I/O时,为什么要使用两个I/O?一行只是一个极端的例子。(我忘记了当首先点击索引变得更有效时的阈值,但我曾经使用10-15%作为经验法则)。Zaratutra的演示也可以使用显式的
gather\u schema\u stats()
。@Alex,作为一个废物,我把它保持得更低,大约5-10%。但是,这取决于很多因素。我指的是萨拉图斯特拉的声明,这不可能是唯一的情况。对于表中行数的索引扫描没有经验法则。@AlexPoole感谢您的澄清。我用这个极端的例子告诉OP,oracle知道自己该做什么。我使用的是oracle 10,在这种情况下,我不想触及现有的查询。我将编写另一个带有提示的查询,并创建所需的解释计划。现在,我将为解释计划使用新的标记,并将其附加到原始的sql id。这是如何做到这一点的逻辑,但我不知道需要更新哪些表来实现这一点。步骤1:SQLI\U D1->PLAN\U ID1;步骤2:SQL\u ID2->PLAN\u ID2;步骤3:SQL\u ID1->PLAN\u ID2