<html>
<head>
    <base href="https://docs.jboss.org/author">
            <link rel="stylesheet" href="/author/s/en/2172/19/5/_/styles/combined.css?spaceKey=TEIID&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://docs.jboss.org/author/display/TEIID/Query+Plans">Query Plans</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://docs.jboss.org/author/display/~shawkins">Steven Hawkins</a>
    </h4>
        <br/>
                         <h4>Changes (10)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >* Object Table - Evaluates OBJECTTABLE <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Node Statistics <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Every node has a set of statistics that are output. These can be used to determine the amount of data flowing through the node.  Before execution a processor plan will not contain node statistics.  Also the statistics are updated as the plan is processed, so typically you&#39;ll want the final statistics after all rows have been processed by the client. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >| Data Bytes Sent | The size of the serialized data result (row and lob values) sent to the client | bytes | <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Reading a Processor Plan <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The processor plan can be obtained in a plain text or xml format.  The plan text format is typically easier to read, while the xml format is easier to process by tooling.  When possible tooling should be used to examine the plans as the tree structures can be deeply nested.   <br> <br>Data flows from the leafs of the tree to the root.  Sub plans for procedure execution can be shown inline, and are differentiated by different indentation.  Given a user query of &quot;SELECT pm1.g1.e1, pm1.g2.e2, pm1.g3.e3 from pm1.g1 inner join (pm1.g2 left outer join pm1.g3 on pm1.g2.e1=pm1.g3.e1) on pm1.g1.e1=pm1.g3.e1&quot; the text for a processor plan that does not push down the joins would look like: <br> <br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">ProjectNode <br>  + Output Columns: <br>    0: e1 (string) <br>    1: e2 (integer) <br>    2: e3 (boolean) <br>  + Cost Estimates:Estimated Node Cardinality: -1.0 <br>  + Child 0: <br>    JoinNode <br>      + Output Columns: <br>        0: e1 (string) <br>        1: e2 (integer) <br>        2: e3 (boolean) <br>      + Cost Estimates:Estimated Node Cardinality: -1.0 <br>      + Child 0: <br>        JoinNode <br>          + Output Columns: <br>            0: e1 (string) <br>            1: e1 (string) <br>            2: e3 (boolean) <br>          + Cost Estimates:Estimated Node Cardinality: -1.0 <br>          + Child 0: <br>            AccessNode <br>              + Output Columns:e1 (string) <br>              + Cost Estimates:Estimated Node Cardinality: -1.0 <br>              + Query:SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 <br>              + Model Name:pm1 <br>          + Child 1: <br>            AccessNode <br>              + Output Columns: <br>                0: e1 (string) <br>                1: e3 (boolean) <br>              + Cost Estimates:Estimated Node Cardinality: -1.0 <br>              + Query:SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g3 AS g_0 ORDER BY c_0 <br>              + Model Name:pm1 <br>          + Join Strategy:MERGE JOIN (ALREADY_SORTED/ALREADY_SORTED) <br>          + Join Type:INNER JOIN <br>          + Join Criteria:pm1.g1.e1=pm1.g3.e1 <br>      + Child 1: <br>        AccessNode <br>          + Output Columns: <br>            0: e1 (string) <br>            1: e2 (integer) <br>          + Cost Estimates:Estimated Node Cardinality: -1.0 <br>          + Query:SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g2 AS g_0 ORDER BY c_0 <br>          + Model Name:pm1 <br>      + Join Strategy:ENHANCED SORT JOIN (SORT/ALREADY_SORTED) <br>      + Join Type:INNER JOIN <br>      + Join Criteria:pm1.g3.e1=pm1.g2.e1 <br>  + Select Columns: <br>    0: pm1.g1.e1 <br>    1: pm1.g2.e2 <br>    2: pm1.g3.e3 <br>{code} <br> <br>Note that the nested join node is using a merge join and expects the source queries from each side to produce the expected ordering for the join.  The parent join is an enhanced sort join which can delay the decision to perform sorting based upon the incoming rows. Note that the outer join from the user query has been modified to an inner join since none of the null inner values can be present in the query result. <br> <br>The same plan in xml form looks like: <br> <br>{code} <br>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; <br>&lt;node name=&quot;ProjectNode&quot;&gt; <br>        &lt;property name=&quot;Output Columns&quot;&gt; <br>                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                &lt;value&gt;e2 (integer)&lt;/value&gt; <br>                &lt;value&gt;e3 (boolean)&lt;/value&gt; <br>        &lt;/property&gt; <br>        &lt;property name=&quot;Cost Estimates&quot;&gt; <br>                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt; <br>        &lt;/property&gt; <br>        &lt;property name=&quot;Child 0&quot;&gt; <br>                &lt;node name=&quot;JoinNode&quot;&gt; <br>                        &lt;property name=&quot;Output Columns&quot;&gt; <br>                                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                                &lt;value&gt;e2 (integer)&lt;/value&gt; <br>                                &lt;value&gt;e3 (boolean)&lt;/value&gt; <br>                        &lt;/property&gt; <br>                        &lt;property name=&quot;Cost Estimates&quot;&gt; <br>                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt; <br>                        &lt;/property&gt; <br>                        &lt;property name=&quot;Child 0&quot;&gt; <br>                                &lt;node name=&quot;JoinNode&quot;&gt; <br>                                        &lt;property name=&quot;Output Columns&quot;&gt; <br>                                                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                                                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                                                &lt;value&gt;e3 (boolean)&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Cost Estimates&quot;&gt; <br>                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Child 0&quot;&gt; <br>                                                &lt;node name=&quot;AccessNode&quot;&gt; <br>                                                        &lt;property name=&quot;Output Columns&quot;&gt; <br>                                                                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                        &lt;property name=&quot;Cost Estimates&quot;&gt; <br>                                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                        &lt;property name=&quot;Query&quot;&gt; <br>                                                                &lt;value&gt;SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                        &lt;property name=&quot;Model Name&quot;&gt; <br>                                                                &lt;value&gt;pm1&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                &lt;/node&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Child 1&quot;&gt; <br>                                                &lt;node name=&quot;AccessNode&quot;&gt; <br>                                                        &lt;property name=&quot;Output Columns&quot;&gt; <br>                                                                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                                                                &lt;value&gt;e3 (boolean)&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                        &lt;property name=&quot;Cost Estimates&quot;&gt; <br>                                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                        &lt;property name=&quot;Query&quot;&gt; <br>                                                                &lt;value&gt;SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g3 AS g_0 <br>                                                                        ORDER BY c_0&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                        &lt;property name=&quot;Model Name&quot;&gt; <br>                                                                &lt;value&gt;pm1&lt;/value&gt; <br>                                                        &lt;/property&gt; <br>                                                &lt;/node&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Join Strategy&quot;&gt; <br>                                                &lt;value&gt;MERGE JOIN (ALREADY_SORTED/ALREADY_SORTED)&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Join Type&quot;&gt; <br>                                                &lt;value&gt;INNER JOIN&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Join Criteria&quot;&gt; <br>                                                &lt;value&gt;pm1.g1.e1=pm1.g3.e1&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                &lt;/node&gt; <br>                        &lt;/property&gt; <br>                        &lt;property name=&quot;Child 1&quot;&gt; <br>                                &lt;node name=&quot;AccessNode&quot;&gt; <br>                                        &lt;property name=&quot;Output Columns&quot;&gt; <br>                                                &lt;value&gt;e1 (string)&lt;/value&gt; <br>                                                &lt;value&gt;e2 (integer)&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Cost Estimates&quot;&gt; <br>                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Query&quot;&gt; <br>                                                &lt;value&gt;SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g2 AS g_0 <br>                                                        ORDER BY c_0&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                        &lt;property name=&quot;Model Name&quot;&gt; <br>                                                &lt;value&gt;pm1&lt;/value&gt; <br>                                        &lt;/property&gt; <br>                                &lt;/node&gt; <br>                        &lt;/property&gt; <br>                        &lt;property name=&quot;Join Strategy&quot;&gt; <br>                                &lt;value&gt;ENHANCED SORT JOIN (SORT/ALREADY_SORTED)&lt;/value&gt; <br>                        &lt;/property&gt; <br>                        &lt;property name=&quot;Join Type&quot;&gt; <br>                                &lt;value&gt;INNER JOIN&lt;/value&gt; <br>                        &lt;/property&gt; <br>                        &lt;property name=&quot;Join Criteria&quot;&gt; <br>                                &lt;value&gt;pm1.g3.e1=pm1.g2.e1&lt;/value&gt; <br>                        &lt;/property&gt; <br>                &lt;/node&gt; <br>        &lt;/property&gt; <br>        &lt;property name=&quot;Select Columns&quot;&gt; <br>                &lt;value&gt;pm1.g1.e1&lt;/value&gt; <br>                &lt;value&gt;pm1.g2.e2&lt;/value&gt; <br>                &lt;value&gt;pm1.g3.e3&lt;/value&gt; <br>        &lt;/property&gt; <br>&lt;/node&gt; <br>{code} <br> <br>Note that the same information appears in each of the plan forms.  In some cases it can actually be easier to follow the simplified format of the debug plan final processor plan.  From the [#Debug Log] the same plan as above would appear as: <br> <br>{code} <br>OPTIMIZATION COMPLETE: <br>PROCESSOR PLAN: <br></td></tr>
            <tr><td class="diff-unchanged" >ProjectNode(0) output=[pm1.g1.e1, pm1.g2.e2, pm1.g3.e3] [pm1.g1.e1, pm1.g2.e2, pm1.g3.e3] <br>  JoinNode(1) [ENHANCED SORT JOIN (SORT/ALREADY_SORTED)] [INNER JOIN] criteria=[pm1.g3.e1=pm1.g2.e1] output=[pm1.g1.e1, pm1.g2.e2, pm1.g3.e3] <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >XML document model queries and proecedure execution (including instead of triggers) use intermediate and final plan forms that include relational plans.  Generally the structure of the xml/procedure plans will closely match their logical forms.  It&#39;s the nested relational plans that will be of interest when analyzing performance issues. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >h1. Debug <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">Plans</span> <span class="diff-added-words"style="background-color: #dfd;">Log</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br>A relational processing plan is created by the optimizer after the logical plan is manipulated by a series of rules.  The application of rules is determined both by the query structure and by the rules themselves.  The node structure of the debug plan resembles that of the processing plan, but the node types more logically represent SQL operations. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> All Nodes <br></td></tr>
            <tr><td class="diff-unchanged" > <br>* ACCESS - a source access or plan execution. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Note that the affect of grouping generates what is effectively an inline view, anon_grp0, to handle the projection of values created by the grouping. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Node Properties <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Each node has a set of applicable properties that are typically shown on the node. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >  ** EST_SELECTIVITY - represents the selectivity of a criteria node <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Rules <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Plan rule manipulate the plan tree, fire other rules, and drive the optimization process.  The structure of the query determines the initial set of rules.  Each rule is designed to perform a narrow set of tasks.  Some rules can be run multiple times.  Some rules require a specific set of precursors to run properly. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >* Validate Where All - ensures criteria is used when required by the source <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Reading a Debug Plan <br></td></tr>
            <tr><td class="diff-unchanged" > <br>As each relational sub plan is optimized, the plan will show what is being optimized and it&#39;s canonical form: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code}   <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">2</span><span class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> XQuery <br></td></tr>
            <tr><td class="diff-unchanged" > <br>XQuery is eligible for specific [optimizations|XQuery Optimization].  Document projection is the most common optimization.  It will be shown in the debug plan as an annotation.  For example with the user query containing &quot;xmltable(&#39;/a/b&#39; passing doc columns x string path &#39;@x&#39;, val string path &#39;/.&#39;)&quot;, the debug plan would show a tree of the document that will effectively be used by the context and path XQuerys: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>When integrating information using a federated query planner it is useful to view the query plans to better understand how information is being accessed and processed, and to troubleshoot problems.</p>

<p>A query plan is a set of instructions created by a query engine for executing a command submitted by a user or application. The purpose of the query plan is to execute the user's query in as efficient a way as possible.</p>

<h1><a name="QueryPlans-GettingaQueryPlan"></a>Getting a Query Plan</h1>

<p>You can get a query plan any time you execute a command. The SQL options available are as follows:</p>

<p><b>SET SHOWPLAN [ON&#124;DEBUG]</b>&#45; Returns the processing plan or the plan and the full planner debug log.  See also the <a href="/author/display/TEIID/SET+Statement" title="SET Statement">SET Statement</a>.</p>

<p>With the above options, the query plan is available from the Statement object by casting to the <tt>org.teiid.jdbc.TeiidStatement</tt> interface or by using the "SHOW PLAN" <a href="/author/display/TEIID/SHOW+Statement" title="SHOW Statement">statement</a>.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Retrieving a Query Plan</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: sql; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
statement.execute("set showplan on");
ResultSet rs = statement.executeQuery("select ...");
TeiidStatement tstatement = statement.unwrap(TeiidStatement.class);
PlanNode queryPlan = tstatement.getPlanDescription();
System.out.println(queryPlan);
</pre>
</div></div>

<p>The query plan is made available automatically in several of Teiid's tools.</p>

<h1><a name="QueryPlans-AnalyzingaQueryPlan"></a>Analyzing a Query Plan</h1>

<p>Once a query plan has been obtained you will most commonly be looking for:</p>

<ul>
        <li>Source pushdown &#45;&#45; what parts of the query that got pushed to each source
        <ul>
                <li>Ensure that any predicates especially against indexes are pushed</li>
        </ul>
        </li>
</ul>


<ul>
        <li>Joins - as federated joins can be quite expensive
        <ul>
                <li>Join ordering - typically influenced by costing</li>
                <li>Join criteria type mismatches.</li>
                <li>Join algorithm used - merge, enhanced merge, nested loop, etc.</li>
        </ul>
        </li>
</ul>


<ul>
        <li>Presence of federated optimizations, such as dependent joins.</li>
</ul>


<ul>
        <li>Ensure hints have the desired affects - see <a href="/author/display/TEIID/Hints+and+Options" title="Hints and Options">Hints and Options</a>, hints in the <a href="/author/display/TEIID/FROM+Clause" title="FROM Clause">FROM Clause</a>, <a href="/author/display/TEIID/Subquery+Optimization" title="Subquery Optimization">Subquery Optimization</a>, and <a href="/author/display/TEIID/Federated+Optimizations" title="Federated Optimizations">Federated Optimizations</a>.</li>
</ul>


<p>All of the above information can be determined from the processing plan. You will typically be interested in analyzing the textual form of the final processing plan.  To understand why particular decisions are made for debugging or support you will want to obtain the full debug log which will contain the intermediate planning steps as well as annotations as to why specific pushdown decisions are made.  </p>

<p>A query plan consists of a set of nodes organized in a tree structure. If you are executing a procedure or generating an XML document from an XML Document Model, the overall query plan will contain additional information related the surrounding procedural execution.</p>

<p>In a procedural context the ordering of child nodes implies the order of execution. In most other situation, child nodes may be executed in any order even in parallel. Only in specific optimizations, such as dependent join, will the children of a join execute serially.</p>

<h1><a name="QueryPlans-RelationalExecutionPlans"></a>Relational Execution Plans</h1>

<p>Relational plans represent the processing plan that is composed of nodes representing building blocks of logical relational operations. Relational processing plans differ from logical debug relational plans in that they will contain additional operations and execution specifics that were chosen by the optimizer.</p>

<p>The nodes for a relational query plan are:</p>

<ul>
        <li>Access - Access a source. A source query is sent to the connection factory associated with the source. [For a dependent join, this node is called Dependent Access.]</li>
</ul>


<ul>
        <li>Dependent Procedure Access - Access a stored procedure on a source using multiple sets of input values.</li>
</ul>


<ul>
        <li>Batched Update - Processes a set of updates as a batch.</li>
</ul>


<ul>
        <li>Project - Defines the columns returned from the node. This does not alter the number of records returned.</li>
</ul>


<ul>
        <li>Project Into - Like a normal project, but outputs rows into a target table.</li>
</ul>


<ul>
        <li>Insert Plan Execution - Similar to a project into, but executes a plan rather than a source query.  Typically created when executing an insert into view with a query expression.</li>
</ul>


<ul>
        <li>Window Function Project - Like a normal project, but includes window functions.</li>
</ul>


<ul>
        <li>Select - Select is a criteria evaluation filter node (WHERE / HAVING).</li>
</ul>


<ul>
        <li>Join - Defines the join type, join criteria, and join strategy (merge or nested loop).</li>
</ul>


<ul>
        <li>Union All - There are no properties for this node, it just passes rows through from it's children.  Depending upon other factors, such as if there is a transaction or the source query concurrency allowed, not all of the union children will execute in parallel.</li>
</ul>


<ul>
        <li>Sort - Defines the columns to sort on, the sort direction for each column, and whether to remove duplicates or not.</li>
</ul>


<ul>
        <li>Dup Remove - Removes duplicate rows.  The processing uses a tree structure to detect duplicates so that results will effectively stream at the cost of IO operations.</li>
</ul>


<ul>
        <li>Grouping - Groups sets of rows into groups and evaluates aggregate functions.</li>
</ul>


<ul>
        <li>Null - A node that produces no rows. Usually replaces a Select node where the criteria is always false (and whatever tree is underneath). There are no properties for this node.</li>
</ul>


<ul>
        <li>Plan Execution - Executes another sub plan. Typically the sub plan will be a non-relational plan.</li>
</ul>


<ul>
        <li>Dependent Procedure Execution - Executes a sub plan using multiple sets of input values.</li>
</ul>


<ul>
        <li>Limit - Returns a specified number of rows, then stops processing. Also processes an offset if present.</li>
</ul>


<ul>
        <li>XML Table - Evaluates XMLTABLE. The debug plan will contain more information about the XQuery/XPath with regards to their optimization - see the XQuery section below or <a href="/author/display/TEIID/XQuery+Optimization" title="XQuery Optimization">XQuery Optimization</a>.</li>
</ul>


<ul>
        <li>Text Table - Evaluates TEXTTABLE</li>
</ul>


<ul>
        <li>Array Table - Evaluates ARRAYTABLE</li>
</ul>


<ul>
        <li>Object Table - Evaluates OBJECTTABLE</li>
</ul>


<h3><a name="QueryPlans-NodeStatistics"></a>Node Statistics</h3>

<p>Every node has a set of statistics that are output. These can be used to determine the amount of data flowing through the node.  Before execution a processor plan will not contain node statistics.  Also the statistics are updated as the plan is processed, so typically you'll want the final statistics after all rows have been processed by the client.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Statistic </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Units </th>
</tr>
<tr>
<td class='confluenceTd'> Node Output Rows </td>
<td class='confluenceTd'> Number of records output from the node </td>
<td class='confluenceTd'> count </td>
</tr>
<tr>
<td class='confluenceTd'> Node Process Time </td>
<td class='confluenceTd'> Time processing in this node only </td>
<td class='confluenceTd'> millisec </td>
</tr>
<tr>
<td class='confluenceTd'> Node Cumulative Process Time </td>
<td class='confluenceTd'> Elapsed time from beginning of processing to end </td>
<td class='confluenceTd'> millisec </td>
</tr>
<tr>
<td class='confluenceTd'> Node Cumulative Next Batch Process Time </td>
<td class='confluenceTd'> Time processing in this node + child nodes </td>
<td class='confluenceTd'> millisec </td>
</tr>
<tr>
<td class='confluenceTd'> Node Next Batch Calls </td>
<td class='confluenceTd'> Number of times a node was called for processing </td>
<td class='confluenceTd'> count </td>
</tr>
<tr>
<td class='confluenceTd'> Node Blocks </td>
<td class='confluenceTd'> Number of times a blocked exception was thrown by this node or a child </td>
<td class='confluenceTd'> count </td>
</tr>
</tbody></table>
</div>


<p>In addition to node statistics, some nodes display cost estimates computed at the node.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Cost Estimates </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Units </th>
</tr>
<tr>
<td class='confluenceTd'> Estimated Node Cardinality </td>
<td class='confluenceTd'> Estimated number of records that will be output from the node; &#45;1 if unknown </td>
<td class='confluenceTd'> count </td>
</tr>
</tbody></table>
</div>


<p>The root node will display additional information.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Top level Statistics </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Units </th>
</tr>
<tr>
<td class='confluenceTd'> Data Bytes Sent </td>
<td class='confluenceTd'> The size of the serialized data result (row and lob values) sent to the client </td>
<td class='confluenceTd'> bytes </td>
</tr>
</tbody></table>
</div>


<h3><a name="QueryPlans-ReadingaProcessorPlan"></a>Reading a Processor Plan</h3>

<p>The processor plan can be obtained in a plain text or xml format.  The plan text format is typically easier to read, while the xml format is easier to process by tooling.  When possible tooling should be used to examine the plans as the tree structures can be deeply nested.  </p>

<p>Data flows from the leafs of the tree to the root.  Sub plans for procedure execution can be shown inline, and are differentiated by different indentation.  Given a user query of "SELECT pm1.g1.e1, pm1.g2.e2, pm1.g3.e3 from pm1.g1 inner join (pm1.g2 left outer join pm1.g3 on pm1.g2.e1=pm1.g3.e1) on pm1.g1.e1=pm1.g3.e1" the text for a processor plan that does not push down the joins would look like:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
ProjectNode
  + Output Columns:
    0: e1 (string)
    1: e2 (integer)
    2: e3 (boolean)
  + Cost Estimates:Estimated Node Cardinality: -1.0
  + Child 0:
    JoinNode
      + Output Columns:
        0: e1 (string)
        1: e2 (integer)
        2: e3 (boolean)
      + Cost Estimates:Estimated Node Cardinality: -1.0
      + Child 0:
        JoinNode
          + Output Columns:
            0: e1 (string)
            1: e1 (string)
            2: e3 (boolean)
          + Cost Estimates:Estimated Node Cardinality: -1.0
          + Child 0:
            AccessNode
              + Output Columns:e1 (string)
              + Cost Estimates:Estimated Node Cardinality: -1.0
              + Query:SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0
              + Model Name:pm1
          + Child 1:
            AccessNode
              + Output Columns:
                0: e1 (string)
                1: e3 (boolean)
              + Cost Estimates:Estimated Node Cardinality: -1.0
              + Query:SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g3 AS g_0 ORDER BY c_0
              + Model Name:pm1
          + Join Strategy:MERGE JOIN (ALREADY_SORTED/ALREADY_SORTED)
          + Join Type:INNER JOIN
          + Join Criteria:pm1.g1.e1=pm1.g3.e1
      + Child 1:
        AccessNode
          + Output Columns:
            0: e1 (string)
            1: e2 (integer)
          + Cost Estimates:Estimated Node Cardinality: -1.0
          + Query:SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g2 AS g_0 ORDER BY c_0
          + Model Name:pm1
      + Join Strategy:ENHANCED SORT JOIN (SORT/ALREADY_SORTED)
      + Join Type:INNER JOIN
      + Join Criteria:pm1.g3.e1=pm1.g2.e1
  + Select Columns:
    0: pm1.g1.e1
    1: pm1.g2.e2
    2: pm1.g3.e3
</pre>
</div></div>

<p>Note that the nested join node is using a merge join and expects the source queries from each side to produce the expected ordering for the join.  The parent join is an enhanced sort join which can delay the decision to perform sorting based upon the incoming rows. Note that the outer join from the user query has been modified to an inner join since none of the null inner values can be present in the query result.</p>

<p>The same plan in xml form looks like:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;node name="ProjectNode"&gt;
        &lt;property name="Output Columns"&gt;
                &lt;value&gt;e1 (string)&lt;/value&gt;
                &lt;value&gt;e2 (integer)&lt;/value&gt;
                &lt;value&gt;e3 (boolean)&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name="Cost Estimates"&gt;
                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt;
        &lt;/property&gt;
        &lt;property name="Child 0"&gt;
                &lt;node name="JoinNode"&gt;
                        &lt;property name="Output Columns"&gt;
                                &lt;value&gt;e1 (string)&lt;/value&gt;
                                &lt;value&gt;e2 (integer)&lt;/value&gt;
                                &lt;value&gt;e3 (boolean)&lt;/value&gt;
                        &lt;/property&gt;
                        &lt;property name="Cost Estimates"&gt;
                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt;
                        &lt;/property&gt;
                        &lt;property name="Child 0"&gt;
                                &lt;node name="JoinNode"&gt;
                                        &lt;property name="Output Columns"&gt;
                                                &lt;value&gt;e1 (string)&lt;/value&gt;
                                                &lt;value&gt;e1 (string)&lt;/value&gt;
                                                &lt;value&gt;e3 (boolean)&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Cost Estimates"&gt;
                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Child 0"&gt;
                                                &lt;node name="AccessNode"&gt;
                                                        &lt;property name="Output Columns"&gt;
                                                                &lt;value&gt;e1 (string)&lt;/value&gt;
                                                        &lt;/property&gt;
                                                        &lt;property name="Cost Estimates"&gt;
                                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt;
                                                        &lt;/property&gt;
                                                        &lt;property name="Query"&gt;
                                                                &lt;value&gt;SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0&lt;/value&gt;
                                                        &lt;/property&gt;
                                                        &lt;property name="Model Name"&gt;
                                                                &lt;value&gt;pm1&lt;/value&gt;
                                                        &lt;/property&gt;
                                                &lt;/node&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Child 1"&gt;
                                                &lt;node name="AccessNode"&gt;
                                                        &lt;property name="Output Columns"&gt;
                                                                &lt;value&gt;e1 (string)&lt;/value&gt;
                                                                &lt;value&gt;e3 (boolean)&lt;/value&gt;
                                                        &lt;/property&gt;
                                                        &lt;property name="Cost Estimates"&gt;
                                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt;
                                                        &lt;/property&gt;
                                                        &lt;property name="Query"&gt;
                                                                &lt;value&gt;SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g3 AS g_0
                                                                        ORDER BY c_0&lt;/value&gt;
                                                        &lt;/property&gt;
                                                        &lt;property name="Model Name"&gt;
                                                                &lt;value&gt;pm1&lt;/value&gt;
                                                        &lt;/property&gt;
                                                &lt;/node&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Join Strategy"&gt;
                                                &lt;value&gt;MERGE JOIN (ALREADY_SORTED/ALREADY_SORTED)&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Join Type"&gt;
                                                &lt;value&gt;INNER JOIN&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Join Criteria"&gt;
                                                &lt;value&gt;pm1.g1.e1=pm1.g3.e1&lt;/value&gt;
                                        &lt;/property&gt;
                                &lt;/node&gt;
                        &lt;/property&gt;
                        &lt;property name="Child 1"&gt;
                                &lt;node name="AccessNode"&gt;
                                        &lt;property name="Output Columns"&gt;
                                                &lt;value&gt;e1 (string)&lt;/value&gt;
                                                &lt;value&gt;e2 (integer)&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Cost Estimates"&gt;
                                                &lt;value&gt;Estimated Node Cardinality: -1.0&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Query"&gt;
                                                &lt;value&gt;SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g2 AS g_0
                                                        ORDER BY c_0&lt;/value&gt;
                                        &lt;/property&gt;
                                        &lt;property name="Model Name"&gt;
                                                &lt;value&gt;pm1&lt;/value&gt;
                                        &lt;/property&gt;
                                &lt;/node&gt;
                        &lt;/property&gt;
                        &lt;property name="Join Strategy"&gt;
                                &lt;value&gt;ENHANCED SORT JOIN (SORT/ALREADY_SORTED)&lt;/value&gt;
                        &lt;/property&gt;
                        &lt;property name="Join Type"&gt;
                                &lt;value&gt;INNER JOIN&lt;/value&gt;
                        &lt;/property&gt;
                        &lt;property name="Join Criteria"&gt;
                                &lt;value&gt;pm1.g3.e1=pm1.g2.e1&lt;/value&gt;
                        &lt;/property&gt;
                &lt;/node&gt;
        &lt;/property&gt;
        &lt;property name="Select Columns"&gt;
                &lt;value&gt;pm1.g1.e1&lt;/value&gt;
                &lt;value&gt;pm1.g2.e2&lt;/value&gt;
                &lt;value&gt;pm1.g3.e3&lt;/value&gt;
        &lt;/property&gt;
&lt;/node&gt;
</pre>
</div></div>

<p>Note that the same information appears in each of the plan forms.  In some cases it can actually be easier to follow the simplified format of the debug plan final processor plan.  From the <a href="#QueryPlans-DebugLog">Debug Log</a> the same plan as above would appear as:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
OPTIMIZATION COMPLETE:
PROCESSOR PLAN:
ProjectNode(0) output=[pm1.g1.e1, pm1.g2.e2, pm1.g3.e3] [pm1.g1.e1, pm1.g2.e2, pm1.g3.e3]
  JoinNode(1) [ENHANCED SORT JOIN (SORT/ALREADY_SORTED)] [INNER JOIN] criteria=[pm1.g3.e1=pm1.g2.e1] output=[pm1.g1.e1, pm1.g2.e2, pm1.g3.e3]
    JoinNode(2) [MERGE JOIN (ALREADY_SORTED/ALREADY_SORTED)] [INNER JOIN] criteria=[pm1.g1.e1=pm1.g3.e1] output=[pm1.g3.e1, pm1.g1.e1, pm1.g3.e3]
      AccessNode(3) output=[pm1.g1.e1] SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0
      AccessNode(4) output=[pm1.g3.e1, pm1.g3.e3] SELECT g_0.e1 AS c_0, g_0.e3 AS c_1 FROM pm1.g3 AS g_0 ORDER BY c_0
    AccessNode(5) output=[pm1.g2.e1, pm1.g2.e2] SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g2 AS g_0 ORDER BY c_0
</pre>
</div></div>

<h1><a name="QueryPlans-OtherPlans"></a>Other Plans</h1>

<p>XML document model queries and proecedure execution (including instead of triggers) use intermediate and final plan forms that include relational plans.  Generally the structure of the xml/procedure plans will closely match their logical forms.  It's the nested relational plans that will be of interest when analyzing performance issues.</p>

<h1><a name="QueryPlans-DebugLog"></a>Debug Log</h1>

<p>A relational processing plan is created by the optimizer after the logical plan is manipulated by a series of rules.  The application of rules is determined both by the query structure and by the rules themselves.  The node structure of the debug plan resembles that of the processing plan, but the node types more logically represent SQL operations.</p>

<h3><a name="QueryPlans-AllNodes"></a>All Nodes</h3>

<ul>
        <li>ACCESS - a source access or plan execution.</li>
        <li>DUP_REMOVE - removes duplicate rows</li>
        <li>JOIN - a join (LEFT OUTER, FULL OUTER, INNER, CROSS, SEMI, etc.)</li>
        <li>PROJECT - a projection of tuple values</li>
        <li>SELECT - a filtering of tuples</li>
        <li>SORT - an ordering operation, which may be inserted to process other operations such as joins</li>
        <li>SOURCE - any logical source of tuples including an inline view, a source access, XMLTABLE, etc.</li>
        <li>GROUP - a grouping operation</li>
        <li>SET_OP - a set operation (UNION/INTERSECT/EXCEPT)</li>
        <li>NULL - a source of no tuples</li>
        <li>TUPLE_LIMIT - row offset / limit</li>
</ul>


<p>User SQL statements after rewrite are converted into a cannonical plan form.  The connonical plan form most closely resembles the initial SQL structure.  For example, a SQL statement such as SELECT max(pm1.g1.e1) FROM pm1.g1 WHERE e2 = 1 creates a logical plan:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
Project(groups=[anon_grp0], props={PROJECT_COLS=[anon_grp0.agg0 AS expr1]})
  Group(groups=[anon_grp0], props={SYMBOL_MAP={anon_grp0.agg0=MAX(pm1.g1.e1)}})
    Select(groups=[pm1.g1], props={SELECT_CRITERIA=e2 = 1})
      Source(groups=[pm1.g1])
</pre>
</div></div>

<p>Here the Source corresponds to the FROM clause, the Select corresponds to the WHERE clause, the Group corresponds to the implied grouping to create the max aggregate, and the Project corresponds to the SELECT clause.</p>

<p>Note that the affect of grouping generates what is effectively an inline view, anon_grp0, to handle the projection of values created by the grouping.</p>

<h3><a name="QueryPlans-NodeProperties"></a>Node Properties</h3>

<p>Each node has a set of applicable properties that are typically shown on the node.</p>

<ul>
        <li>Access Properties
        <ul>
                <li>ATOMIC_REQUEST - The final form of a source request</li>
                <li>MODEL_ID - The metadata object for the target model/schema</li>
                <li>PROCEDURE_CRITERIA/PROCEDURE_INPUTS/PROCEDURE_DEFAULTS - Used in planning procedureal relational queries</li>
                <li>IS_MULTI_SOURCE - set to true when the node represents a multi-source access</li>
                <li>SOURCE_NAME - used to track the multi-source source name</li>
                <li>CONFORMED_SOURCES - tracks the set of conformed sources when the conformed extension metadata is used</li>
                <li>SUB_PLAN/SUB_PLANS - used in multi-source planning</li>
        </ul>
        </li>
        <li>SET_OPERATION/USE_ALL - defines the set operation (UNION/INTERSECT/EXCEPT) and if all rows or distinct rows are used.</li>
        <li>Join Properties
        <ul>
                <li>JOIN_CRITERIA - all join predicates</li>
                <li>JOIN_TYPE - type of join (INNER, LEFT OUTER, etc.)</li>
                <li>JOIN_STRATEGY - the algorithm to use (nested loop, merge, etc.)</li>
                <li>LEFT_EXPRESSIONS - the expressions in equi-join predicates that originate from the left side of the join</li>
                <li>RIGHT_EXPRESSIONS - the expressions in equi-join predicates that originate from the right side of the join</li>
                <li>DEPENDENT_VALUE_SOURCE - set if a dependent join is used</li>
                <li>NON_EQUI_JOIN_CRITERIA - non-equi join predicates</li>
                <li>SORT_LEFT - if the left side needs sorted for join processing</li>
                <li>SORT_RIGHT - if the right side needs sorted for join processing</li>
                <li>IS_OPTIONAL - if the join is optional</li>
                <li>IS_LEFT_DISTINCT - if the left side is distinct with respect to the equi join predicates</li>
                <li>IS_RIGHT_DISTINCT - if the right side is distinct with respect to the equi join predicates</li>
                <li>IS_SEMI_DEP - if the dependent join represents a semi-join</li>
                <li>PRESERVE - if the preserve hint is preserving the join order</li>
        </ul>
        </li>
        <li>Project Properties
        <ul>
                <li>PROJECT_COLS - the expressions projected</li>
                <li>INTO_GROUP - the group targeted if this is a select into or insert with a query expression</li>
                <li>HAS_WINDOW_FUNCTIONS - true if window functions are used</li>
                <li>CONSTRAINT - the constraint that must be met if the values are being projected into a group</li>
        </ul>
        </li>
        <li>Select Properties
        <ul>
                <li>SELECT_CRITERIA - the filter</li>
                <li>IS_HAVING - if the filter is applied after grouping</li>
                <li>IS_PHANTOM - true if the node is marked for removal, but temporarily left in the plan.</li>
                <li>IS_TEMPORARY - inferred criteria that may not be used in the final plan</li>
                <li>IS_COPIED - if the criteria has already been processed by rule copy criteria</li>
                <li>IS_PUSHED - if the criteria is pushed as far as possible</li>
                <li>IS_DEPENDENT_SET - if the criteria is the filter of a dependent join</li>
        </ul>
        </li>
        <li>Sort Properties
        <ul>
                <li>SORT_ORDER - the order by that defines the sort</li>
                <li>UNRELATED_SORT - if the ordering includes a value that is not being projected</li>
                <li>IS_DUP_REMOVAL - if the sort should also perform duplicate removal over the entire projection</li>
        </ul>
        </li>
        <li>Source Properties - many source properties also become present on associated access nodes
        <ul>
                <li>SYMBOL_MAP - the mapping from the columns above the source to the projected expressions.  Also present on Group nodes</li>
                <li>PARTITION_INFO - the partitioning of the union branches</li>
                <li>VIRTUAL_COMMAND - if the source represents an view or inline view, the query that defined the view</li>
                <li>MAKE_DEP - hint information</li>
                <li>PROCESSOR_PLAN - the processor plan of a non-relational source (typically from the NESTED_COMMAND)</li>
                <li>NESTED_COMMAND - the non-relational command</li>
                <li>TABLE_FUNCTION - the table function (XMLTABLE, OBJECTTABLE, etc.) defining the source</li>
                <li>CORRELATED_REFERENCES - the correlated references for the nodes below the source</li>
                <li>MAKE_NOT_DEP - if make not dep is set</li>
                <li>INLINE_VIEW - If the source node represents an inline view</li>
                <li>NO_UNNEST - if the no_unnest hint is set</li>
                <li>MAKE_IND - if the make ind hint is set</li>
                <li>SOURCE_HINT - the source hint.  See <a href="/author/display/TEIID/Federated+Optimizations" title="Federated Optimizations">Federated Optimizations</a>.</li>
                <li>ACCESS_PATTERNS - access patterns yet to be satisfied</li>
                <li>ACCESS_PATTERN_USED - satisfied access patterns</li>
                <li>REQUIRED_ACCESS_PATTERN_GROUPS -  groups needed to satisfy the access patterns.  Used in join planning.</li>
        </ul>
        </li>
        <li>Group Properties
        <ul>
                <li>GROUP_COLS - the grouping columns</li>
                <li>ROLLUP - if the grouping includes a rollup</li>
        </ul>
        </li>
        <li>Tuple Limit Properties
        <ul>
                <li>MAX_TUPLE_LIMIT - expression that evaluates to the max number of tuples generated</li>
                <li>OFFSET_TUPLE_COUNT - Expression that evaluates to the tuple offset of the starting tuple</li>
                <li>IS_IMPLICIT_LIMIT - if the limit is created by the rewriter as part of a subquery optimization</li>
                <li>IS_NON_STRICT - if the unordered limit should not be enforced strictly</li>
        </ul>
        </li>
        <li>General and Costing Properties
        <ul>
                <li>OUTPUT_COLS - the output columns for the node.  Is typically set after rule assign output elements.</li>
                <li>EST_SET_SIZE - represents the estimated set size this node would produce for a sibling node as the independent node in a dependent join scenario</li>
                <li>EST_DEP_CARDINALITY - value that represents the estimated cardinality (amount of rows) produced by this node as the dependent node in a dependent join scenario</li>
                <li>EST_DEP_JOIN_COST - value that represents the estimated cost of a dependent join (the join strategy for this could be Nested Loop or Merge)</li>
                <li>EST_JOIN_COST - value that represents the estimated cost of a merge join (the join strategy for this could be Nested Loop or Merge)</li>
                <li>EST_CARDINALITY - represents the estimated cardinality (amount of rows) produced by this node</li>
                <li>EST_COL_STATS - column statistics including number of null values, distinct value count, etc.</li>
                <li>EST_SELECTIVITY - represents the selectivity of a criteria node</li>
        </ul>
        </li>
</ul>


<h3><a name="QueryPlans-Rules"></a>Rules</h3>

<p>Plan rule manipulate the plan tree, fire other rules, and drive the optimization process.  The structure of the query determines the initial set of rules.  Each rule is designed to perform a narrow set of tasks.  Some rules can be run multiple times.  Some rules require a specific set of precursors to run properly.</p>

<ul>
        <li>Access Pattern Validation - ensures that all access patterns have been satisfied</li>
        <li>Apply Security - applies row and column level security</li>
        <li>Assign Output Symbol - determines the output of every node and minimizes projection</li>
        <li>Calculate Cost - adds costing information to the plan</li>
        <li>Choose Dependent - choose dependent joins based upon the cost/hints</li>
        <li>Choose Join Strategy - choose the join strategy base upon the cost</li>
        <li>Clean Criteria - removes phantom criteria</li>
        <li>Collapse Source - takes all of the nodes below an access node and creates a SQL query representation</li>
        <li>Copy Criteria - copies criteria based upon join predicates</li>
        <li>Decompose Join - optimizes joins over partitioned unions</li>
        <li>Implement Join Strategy - adds necessary sort and other nodes to process the chosen join strategy</li>
        <li>Merge Criteria - combines select nodes and can convert subqueries to semi-joins</li>
        <li>Merge Virtual - removes view and inline view layers</li>
        <li>Place Access - places access nodes under source nodes</li>
        <li>Plan Joins - determines the best join order</li>
        <li>Plan Procedures - plans procedures that appear in procedural relational queries</li>
        <li>Plan Sorts - optimizations around sorting, such as combining sort operations or moving projection</li>
        <li>Plan Unions - reorders union children for more pushdown</li>
        <li>Plan Aggregates - performs aggregate decomposition over a join or union</li>
        <li>Push Limit - pushes the affect of a limit node further into the plan</li>
        <li>Push Non-Join Criteria - pushes non-equi join conditions out of the on clause when possible</li>
        <li>Push Select Criteria - pushed select nodes as far as possible</li>
        <li>Raise Access - raises access nodes, which increases the work done by source queries</li>
        <li>Raise Null - raises null nodes</li>
        <li>Remove Optional Joins - removes joins that are marked as or determined to be optional</li>
        <li>Substitute Expressions - used only when a function based index is present</li>
        <li>Validate Where All - ensures criteria is used when required by the source</li>
</ul>


<h3><a name="QueryPlans-ReadingaDebugPlan"></a>Reading a Debug Plan</h3>

<p>As each relational sub plan is optimized, the plan will show what is being optimized and it's canonical form:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
OPTIMIZE: 
SELECT e1 FROM (SELECT e1 FROM pm1.g1) AS x

----------------------------------------------------------------------------
GENERATE CANONICAL: 
SELECT e1 FROM (SELECT e1 FROM pm1.g1) AS x

CANONICAL PLAN: 
Project(groups=[x], props={PROJECT_COLS=[e1]})
  Source(groups=[x], props={NESTED_COMMAND=SELECT e1 FROM pm1.g1, SYMBOL_MAP={x.e1=e1}})
    Project(groups=[pm1.g1], props={PROJECT_COLS=[e1]})
      Source(groups=[pm1.g1])
</pre>
</div></div>

<p>With more complicated user queries, such as a procedure invocation or one containing subqueries, the sub plans may be nested within the overall plan.  Each plan ends by showing the final processing plan:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
----------------------------------------------------------------------------
OPTIMIZATION COMPLETE:
PROCESSOR PLAN:
AccessNode(0) output=[e1] SELECT g_0.e1 FROM pm1.g1 AS g_0
</pre>
</div></div>

<p>The affect of rules can be seen by the state of the plan tree before and after the rule fires.  For example, the debug log below shows the application of rule merge virtual, which will remove the "x" inline view layer:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
EXECUTING AssignOutputElements

AFTER: 
Project(groups=[x], props={PROJECT_COLS=[e1], OUTPUT_COLS=[e1]})
  Source(groups=[x], props={NESTED_COMMAND=SELECT e1 FROM pm1.g1, SYMBOL_MAP={x.e1=e1}, OUTPUT_COLS=[e1]})
    Project(groups=[pm1.g1], props={PROJECT_COLS=[e1], OUTPUT_COLS=[e1]})
      Access(groups=[pm1.g1], props={SOURCE_HINT=null, MODEL_ID=Schema name=pm1, nameInSource=null, uuid=3335, OUTPUT_COLS=[e1]})
        Source(groups=[pm1.g1], props={OUTPUT_COLS=[e1]})


============================================================================
EXECUTING MergeVirtual

AFTER: 
Project(groups=[pm1.g1], props={PROJECT_COLS=[e1], OUTPUT_COLS=[e1]})
  Access(groups=[pm1.g1], props={SOURCE_HINT=null, MODEL_ID=Schema name=pm1, nameInSource=null, uuid=3335, OUTPUT_COLS=[e1]})
    Source(groups=[pm1.g1])
</pre>
</div></div>

<p>Some important planning decisions are shown in the plan as they occur as an annotation.  For example the snippet below shows that the access node could not be raised as the parent select node contained an unsupported subquery.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
Project(groups=[pm1.g1], props={PROJECT_COLS=[e1], OUTPUT_COLS=null})
  Select(groups=[pm1.g1], props={SELECT_CRITERIA=e1 IN /*+ NO_UNNEST */ (SELECT e1 FROM pm2.g1), OUTPUT_COLS=null})
    Access(groups=[pm1.g1], props={SOURCE_HINT=null, MODEL_ID=Schema name=pm1, nameInSource=null, uuid=3341, OUTPUT_COLS=null})
      Source(groups=[pm1.g1], props={OUTPUT_COLS=null})


============================================================================
EXECUTING RaiseAccess
LOW Relational Planner SubqueryIn is not supported by source pm1 - e1 IN /*+ NO_UNNEST */ (SELECT e1 FROM pm2.g1) was not pushed

AFTER: 
Project(groups=[pm1.g1])
  Select(groups=[pm1.g1], props={SELECT_CRITERIA=e1 IN /*+ NO_UNNEST */ (SELECT e1 FROM pm2.g1), OUTPUT_COLS=null})
    Access(groups=[pm1.g1], props={SOURCE_HINT=null, MODEL_ID=Schema name=pm1, nameInSource=null, uuid=3341, OUTPUT_COLS=null})
      Source(groups=[pm1.g1])
</pre>
</div></div>  

<h3><a name="QueryPlans-XQuery"></a>XQuery</h3>

<p>XQuery is eligible for specific <a href="/author/display/TEIID/XQuery+Optimization" title="XQuery Optimization">optimizations</a>.  Document projection is the most common optimization.  It will be shown in the debug plan as an annotation.  For example with the user query containing "xmltable('/a/b' passing doc columns x string path '@x', val string path '/.')", the debug plan would show a tree of the document that will effectively be used by the context and path XQuerys:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
MEDIUM XQuery Planning Projection conditions met for /a/b - Document projection will be used
childelement(Q{}a)
  childelement(Q{}b)
    attributeattribute(Q{}x)
      childtext()
    childtext()
</pre>
</div></div>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://docs.jboss.org/author/users/removespacenotification.action?spaceKey=TEIID">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://docs.jboss.org/author/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://docs.jboss.org/author/display/TEIID/Query+Plans">View Online</a>
        |
        <a href="https://docs.jboss.org/author/pages/diffpagesbyversion.action?pageId=18646297&revisedVersion=18&originalVersion=17">View Changes</a>
                |
        <a href="https://docs.jboss.org/author/display/TEIID/Query+Plans?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>