One query string (represented by SQL_ID
) can have several different execution plans. All are stored in V$SQL_PLAN
and identified by different CHILD_NUMBER
.
The function DBMS_XPLAN.DISPLAY_CURSOR has a second parameter, where you can pass the required child_number. If you omit the second parameter, the function returns all child cursors, so effectively you should see all rows from V$SQL_PLAN (but in different execution plans).
To see which child cursor is actually used, you may check the V$SESSION
column SQL_CHILD_NUMBER
.
Update for 12c
This obvious answer to the question why has V$SQL_PLAN
more rows than DBMS_XPLAN.DISPLAY_CURSOR
was the most probable one until 12c version of Oracle. 12c introduced Adaptive Query Optimization
where some operation are marked by the optimizer as inactive. This choice can be switched by the execution engine.
Such plans can be recognized by the operation STATISTICS COLLECTOR
. The STATISTICS COLLECTOR tests on execution the actual number of rows
and if it is higher than the from optimize calculated point of inflection
switches the plan. (Example - nested loops work fine for few rows, but
for a large number its "hanging"; contrary hash join work good for large number of rows, but for few rows it has a high overhead.
Point of inflection should correspond to such number of row, where the costs are estimated the same).
Unfortunately there is no column in V$SQL_PLAN
identifying the inactive operations.
This blog makes observation, that this information could be extracted the the column OTHER_XML
using the element display_map
attribute @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"/>
....