在Oracle 12.1上运行我正在寻找在他们的计划中进行全表扫描的SQL 当我查看时:
Excel::_ApplicationPtr &app;
CComObject<TestEvent> *obj = new CComObject<TestEvent>;
obj->Init(this);
variant_t v = static_cast<IDispatch *>(obj);
app->Run("SetEventSinkTest", v);
我得到21行,其中一行有TABLE ACCESS FULL
但是,如果我使用相同的sql _id调用它:
select * from V$SQL_PLAN where sql_id = '89p47f9wnnwg9'
我从计划表中只得到13行,并且缺少TABLE ACCESS FULL。
为何出现差异?
答案 0 :(得分:3)
一个查询字符串(由SQL_ID
表示)可以有多个不同的执行计划。所有内容都存储在V$SQL_PLAN
中,并由不同的CHILD_NUMBER
标识。
函数DBMS_XPLAN.DISPLAY_CURSOR有第二个参数,您可以在其中传递所需的child_number。如果省略第二个参数,该函数将返回所有子游标,因此您应该看到V $ SQL_PLAN中的所有行(但在不同的执行计划中)。
要查看实际使用的子光标,您可以查看V$SESSION
列SQL_CHILD_NUMBER
。
更新12c
这个问题的明显答案为什么V$SQL_PLAN
行多于DBMS_XPLAN.DISPLAY_CURSOR
是12c版本的Oracle之前最可能的版本。 12c介绍Adaptive Query Optimization
其中某些操作被优化程序标记为非活动状态。该选择可以由执行引擎切换。
此类计划可由操作STATISTICS COLLECTOR
识别。 STATISTICS COLLECTOR测试执行的实际行数
如果它高于from优化计算point of inflection
,则切换计划。 (示例 - 嵌套循环适用于少数行,但是
对于大量的“悬挂”;相反的散列连接适用于大量行,但对于少数行,它具有很高的开销。
拐点应该对应于这样的行数,其中成本估计相同)。
不幸的是,V$SQL_PLAN
中没有列标识非活动操作。
此blog进行了观察,可以使用元素OTHER_XML
属性display_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"/>
....
答案 1 :(得分:0)
Per Jonathan Lewis,
这是一个自适应计划 - 有两个拐点(由STATISTICS COLLETOR指示)操作,Oracle可以做出运行时决策。
在调用display_cursor时将'ALL'更改为'adaptive',您将看到所有行和说明如何识别“非活动”行的说明
此致 乔纳森刘易斯
所以
((Activity)mContext).getSupportFragmentManager().findFragmentByTag("Your Fragment Name")
返回该行,但标记为“未使用”。