只是要求澄清 2 之间的区别。据我所知,EXPLAIN PLAN 为您提供理论执行计划,而 DBMS_XPLAN.DISPLAY_CURSOR 为您提供带有语句执行统计信息的实际执行计划。
EXPLAIN PLAN 将此数据存储在 PLAN_TABLE 中,而 DBMS_XPLAN 使用 V$SQL_PLAN、V$SQL_PLAN_STATISTICS 和 V$SQL_PLAN_STATISTICS_ALL View 获取其信息。
但是,为了让 DISPLAY_CURSOR 收集该语句的实际运行时统计信息,需要设置 /*+ gather_plan_statistics */
暗示。否则,只有 V$SQL_PLAN 被填充,它只会给你执行计划而不是实际的执行统计信息。只有 /*+ gather_plan_statistics */
其中填充了 V$SQL_PLAN_STATISTICS。
所以我的问题是,如果我不使用 gather_plan_statistics 提示,EXPLAIN PLAN 和 DISPLAY_CURSOR 是否总是给我相同的执行计划(对于同一个语句)?
最佳答案
差异不是很微妙,它们是巨大的。
正如您正确提到的,解释计划将其数据存储在 plan_table 中,并从该表中查询计划。这意味着不执行 sql,只要求优化器提供计划。在该设置中,计划在很大程度上取决于您运行解释计划的 session 的优化器环境。
使用 DBMS_XPLAN.DISPLAY_CURSOR,您可以获得之前执行过的计划。该计划不是通过发出 DBMS_XPLAN.DISPLAY_CURSOR 来存储的;它存储在 v$ 结构中,因为它已被执行。
在 session 中,您可以运行
select * from dual;
select * from table(dbms_xplan.display_cursor);
查询在“select from dual”中执行,这也会导致创建计划并将其存储在 v$ 结构中。 display_cursor 只是找到最后执行的游标并显示它遵循的计划。使用此设置/*+ gather_plan_statistics */没有附加值,因为计划及其统计信息已经存在于 shared_pool 中。
您的另一个问题,计划是否始终相同取决于许多因素。变量是否相同?,您是否使用自适应游标共享,您是否使用 SQL Plan Stability ...
你的问题:给explain plan和display_cursor同一个plan?我不会依赖它,因为使用解释计划,该计划取决于您的 session 优化器环境。 display_cursor 是更好的方法,最好使用由应用程序创建的命名游标。如果您不使用 SQL 计划稳定性,则计划可能会在优化器统计信息更改时更改。如果您使用自适应光标共享,则当变量更改时,计划可能会更改。
可以在 Jonathan Lewis 中找到有关采样开销的一些不错的读物。博客。同样来自乔纳森:gather_plan_statistics 与使用/*+ gather_plan_statistics */提示相反,我通常更聪明地使用 statistics_level 设置 'all' 进行调试。提示更改代码并导致新的 sql_id。
我希望这有帮助。
关于sql - DBMS_XPLAN.DISPLAY_CURSOR 与未使用gather_plan_statistics 提示的解释计划,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9388837/