Vla*_*cea 4 sql database oracle optimization sql-execution-plan
根据这个Oracle 文档,我可以假设优化器推迟了硬解析,并且直到第一次执行准备好的语句时才生成执行计划:
“答案是一种称为绑定窥视的现象。早些时候,当您在绑定变量值设置为“NY”的情况下运行该查询时,优化器必须第一次进行硬解析,并且在这样做时它会窥视绑定变量看看它被赋予了什么价值。”
但是,当对带有绑定参数的准备好的语句执行 EXPLAIN PLAN 时,我们会得到一个执行计划。马库斯·维南德 (Markus Winand)在他的网站上表示:
“使用绑定参数时,优化器没有可用的具体值来确定它们的频率。然后它只是假设均匀分布并始终获得相同的行计数估计和成本值。最后,它将始终选择相同的执行计划。 ”
哪一个是真的?当使用均匀分布值模型准备语句时是否生成执行计划,或者是否将硬解析推迟到第一次执行时间。
这个讨论忽略了关于绑定变量、解析和绑定查看的一个非常重要的点;这就是直方图!仅当相关列具有直方图时,绑定变量才会成为问题。如果没有直方图,就无需查看该值。Oracle 没有关于数据分布的信息,并且只会使用纯数学(不同值、空值数量、行数等)来查找相关过滤器的选择性。
绑定和直方图是逻辑上相反的。您可以使用绑定变量为所有查询获取一个执行计划。您可以使用直方图为不同的搜索值获取不同的执行计划。绑定窥视试图克服这个问题。但它在这方面做得并不好。许多人实际上将绑定窥视功能描述为“错误”。Oracle 11g 中的自适应游标共享可以更好地解决这个问题。
实际上我看到了很多直方图。我通常禁用直方图(方法 opt=>'for all columns size 1',并且仅在我真正需要它们时才创建它们。
然后回到最初的问题:“Oracle 在解析准备好的语句时是否选择默认执行计划?” 解析不是一项活动。解析涉及语法检查、语义分析(表和列是否存在、您是否有权访问表)、查询重写(Oracle 可能会以更好的方式重写查询 - 例如 - 如果我们使用过滤器 a=b 和 b =c,那么Oracle可以添加过滤器a=c),当然还可以找到执行计划。实际上,我们区分不同类型的解析——软解析和硬解析。硬解析是 Oracle 还必须为查询创建执行计划的地方。这是一项非常昂贵的活动。
回到问题。解析并不真正关心您是否使用绑定变量。不同的是,如果你使用bind,你可能只需要进行软解析。使用绑定变量,您的查询每次运行时都会看起来相同(因此获得相同的 hash_value)。当您运行查询时,Oracle 将检查(在库缓存中)以查看是否已准备好查询的执行计划。这不是默认计划,而是一个已经存在的计划,因为其他人已经执行了相同的查询(并使 Oracle 进行硬解析,为该查询生成执行计划)并且执行计划尚未从缓存中过期。这不是默认计划。这只是优化器在解析时认为是查询的最佳选择的计划。当您使用 Oracle 12c 时,它实际上变得更加复杂。Oracle中有12个Adaptive Executionplans——这意味着执行计划有一个替代方案。它可以从嵌套循环开始,如果它意识到基数估计错误,它可以在查询执行过程中切换到散列连接。它还具有称为自适应统计和 sql 计划指令的功能。所有这些都是为了让优化器和 Oracle 在运行 SQL 时做出更好的选择:-)