DBMS_XPLAN.DISPLAY_游标中的sql计划不一致

DBMS_XPLAN.DISPLAY_游标中的sql计划不一致,sql,oracle,explain,Sql,Oracle,Explain,在Oracle 12.1上运行时,我正在寻找计划中包含完整表扫描的SQL。 当我往里看时: select * from V$SQL_PLAN where sql_id = '89p47f9wnnwg9' 我返回了21行,其中一行的表访问权限已满 但是,如果我为相同的sql\u id调用此函数,则: SELECT * FROM TABLE ( DBMS_XPLAN.DISPLAY_CURSOR ('89p47f9wnnwg9', 0, 'ALL')) 我从plan表中得到的结果只有13行,并

在Oracle 12.1上运行时,我正在寻找计划中包含完整表扫描的SQL。
当我往里看时:

select * from V$SQL_PLAN where sql_id = '89p47f9wnnwg9'

我返回了21行,其中一行的表访问权限已满

但是,如果我为相同的sql\u id调用此函数,则:

SELECT * FROM TABLE ( DBMS_XPLAN.DISPLAY_CURSOR ('89p47f9wnnwg9', 0, 'ALL'))
我从plan表中得到的结果只有13行,并且缺少表访问完整

为什么会有差异?

一个查询字符串(由
SQL\u ID
表示)可以有多个不同的执行计划。所有这些都存储在
V$SQL\u计划中
并由不同的
子\u编号
标识

该函数还有第二个参数,您可以在其中传递所需的子_编号。如果省略第二个参数,该函数将返回所有子游标,因此您应该可以有效地看到V$SQL\u计划中的所有行(但在不同的执行计划中)

要查看实际使用的子光标,可以检查
V$SESSION
SQL\u child\u NUMBER

12c的更新

这是对为什么
V$SQL\u PLAN
的行数比
DBMS\u XPLAN.DISPLAY\u CURSOR
在甲骨文的12c版本之前,最有可能是这个版本。12c引入 其中一些操作被优化器标记为非活动。此选项可由执行引擎切换。 此类计划可由操作
统计采集器
识别。统计数据收集器在执行时测试实际行数
如果它高于从优化计算的
拐点
切换计划。(示例-嵌套循环对少数行适用,但 对于大量的行,它的“挂起”;相反的散列连接适用于大量的行,但对于少数行,它的开销很高。 拐点应与此类行数相对应,其中成本估算相同)

不幸的是,
V$SQL\u计划
中没有标识非活动操作的列

这样可以观察到,可以使用元素
display\u map
属性
@skp

 <display_map>
    <row op="1" dis="1" par="0" prt="0" dep="1" skp="0"/>
    <row op="2" dis="2" par="1" prt="0" dep="2" skp="0"/>
    <row op="3" dis="2" par="2" prt="0" dep="2" skp="1"/>
    ....

....
根据乔纳森·刘易斯

这是一个自适应计划—Oracle可以在两个拐点(由STATISTICS COLLETOR指示)操作中做出运行时决策

将通话中的“ALL”更改为“adaptive”以显示光标,您将看到所有行和一条说明如何识别“inactive”行的注释

问候 乔纳森·刘易斯

所以


返回行,但标记为“未使用”。

检查V$SQL\u计划中的列
子\u编号。上面的查询显示了所有子游标,下面只显示了child_number=0V$SQL_PLAN.child_number为0的游标,这是我传入的,但仍然不匹配。我无法使用V$Session,因为其中可能不再有记录。使用V$SQLAREA,在Oracle站点上发布了相同的问题,得到了一个有效的答案:这是一个自适应计划-Oracle可以在两个拐点(由统计数据收集器指示)操作中做出运行时决策。将通话中的'ALL'更改为'adaptive'以显示光标,您将看到所有行和一条说明如何识别“非活动”行的注释Lewis@OldProgrammer非常抱歉回答不恰当。在查询
V$SQL\u PLAN
时,我被缺少的
CHILD\u NUMBER
谓词误导了。我延长了我的回答。
SELECT * FROM TABLE ( DBMS_XPLAN.DISPLAY_CURSOR ('89p47f9wnnwg9', null, 'ADAPTIVE'))