<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – Query plan information and structure</title>
    <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/</link>
    <description>Recent content in Query plan information and structure on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/admin/managing-queries/query-plans/query-plan-information-and-structure/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Admin: Query plan statistics</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/query-plan-statistics/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/query-plan-statistics/</guid>
      <description>
        
        
        &lt;p&gt;If you query a table whose statistics are unavailable or out-of-date, the optimizer might choose a sub-optimal query plan.&lt;/p&gt;
&lt;p&gt;You can resolve many issues related to table statistics by calling 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/functions/performance-analysis-functions/statistics-management-functions/analyze-statistics/#&#34;&gt;ANALYZE_STATISTICS&lt;/a&gt;&lt;/code&gt;. This function let you update statistics at various scopes: one or more table columns, a single table, or all database tables.&lt;/p&gt;
&lt;p&gt;If you update statistics and find that the query still performs sub-optimally, run your query through Database Designer and choose incremental design as the design type.&lt;/p&gt;
&lt;p&gt;For detailed information about updating database statistics, see &lt;a href=&#34;../../../../../en/admin/collecting-db-statistics/#&#34;&gt;Collecting database statistics&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;statistics-hints-in-query-plans&#34;&gt;Statistics hints in query plans&lt;/h2&gt;
&lt;p&gt;Query plans can contain information about table statistics through two hints: &lt;code&gt;NO STATISTICS&lt;/code&gt; and &lt;code&gt;STALE STATISTICS&lt;/code&gt;. For example, the following query plan fragment includes &lt;code&gt;NO STATISTICS&lt;/code&gt; to indicate that histograms are unavailable:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;| | +-- Outer -&amp;gt; STORAGE ACCESS for fact [Cost: 604, Rows: 10K (NO STATISTICS)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following query plan fragment includes &lt;code&gt;STALE STATISTICS&lt;/code&gt; to indicate that the predicate has fallen outside the histogram range:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;| | +-- Outer -&amp;gt; STORAGE ACCESS for fact [Cost: 35, Rows: 1 (STALE STATISTICS)]
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: Cost and rows path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/cost-and-rows-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/cost-and-rows-path/</guid>
      <description>
        
        
        &lt;p&gt;The following EXPLAIN output shows the &lt;code&gt;Cost&lt;/code&gt; operator:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; Access Path: +-SELECT  LIMIT 10 [&lt;span class=&#34;code-input&#34;&gt;Cost&lt;/span&gt;: 370, Rows: 10] (PATH ID: 0)
 |  Output Only: 10 tuples
 |  Execute on: Query Initiator
 | +---&amp;gt; SORT &lt;span class=&#34;code-input&#34;&gt;[Cost&lt;/span&gt;: 370, Rows: 544] (PATH ID: 1)
 | |      Order: customer_dimension.customer_name ASC
 | |      Output Only: 10 tuples
 | |      Execute on: Query Initiator
 | | +---&amp;gt; STORAGE ACCESS for customer_dimension &lt;span class=&#34;code-input&#34;&gt;[Cost&lt;/span&gt;: 331, Rows: 544] (PATH ID: 2)
 | | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | | |      Materialize: customer_dimension.customer_state, customer_dimension.customer_name
 | | |      Filter: (customer_dimension.customer_gender = &amp;#39;Male&amp;#39;)
 | | |      Filter: (customer_dimension.customer_state = ANY (ARRAY[&amp;#39;MA&amp;#39;, &amp;#39;NH&amp;#39;]))
 | | |      Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;Row&lt;/code&gt; operator is the number of rows the optimizer estimates the query will return. Letters after numbers refer to the units of measure (K=thousand, M=million, B=billion, T=trillion), so the output for the following query indicates that the number of rows to return is 50 &lt;em&gt;thousand&lt;/em&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT customer_gender FROM customer_dimension;
 Access Path:
 +-STORAGE ACCESS for customer_dimension [Cost: 17, Rows: 50K (3 RLE)] (PATH ID: 1)
 |  Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 |  Materialize: customer_dimension.customer_gender
 |  Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The reference to (3 RLE) in the STORAGE ACCESS path means that the optimizer estimates that the storage access operator returns 50K rows. Because the column is run-length encoded (RLE), the real number of RLE rows returned is only three rows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1 row for female&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1 row for male&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1 row that represents unknown (NULL) gender&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

See &lt;a href=&#34;../../../../../en/admin/managing-queries/query-plans/#&#34;&gt;Query plans&lt;/a&gt; for more information about how the optimizer estimates cost.

&lt;/div&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Projection path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/projection-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/projection-path/</guid>
      <description>
        
        
        &lt;p&gt;You can see which &lt;a class=&#34;glosslink&#34; href=&#34;../../../../../en/glossary/projection/&#34; title=&#34;Optimized collections of table columns that provide physical storage for data.&#34;&gt;projections&lt;/a&gt; the optimizer chose for the query plan by looking at the &lt;code&gt;Projection&lt;/code&gt; path in the textual output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;EXPLAIN SELECT
   customer_name,
   customer_state
 FROM customer_dimension
 WHERE customer_state in (&amp;#39;MA&amp;#39;,&amp;#39;NH&amp;#39;)
 AND customer_gender = &amp;#39;Male&amp;#39;
 ORDER BY customer_name
 LIMIT 10;
 Access Path:
 +-SELECT  LIMIT 10 [Cost: 370, Rows: 10] (PATH ID: 0)
 |  Output Only: 10 tuples
 |  Execute on: Query Initiator
 | +---&amp;gt; SORT [Cost: 370, Rows: 544] (PATH ID: 1)
 | |      Order: customer_dimension.customer_name ASC
 | |      Output Only: 10 tuples
 | |      Execute on: Query Initiator
 | | +---&amp;gt; STORAGE ACCESS for customer_dimension [Cost: 331, Rows: 544] (PATH ID: 2)
 | | |      &lt;span class=&#34;code-input&#34;&gt;Projection&lt;/span&gt;: public.customer_dimension_DBD_1_rep_vmart_vmart_node0001
 | | |      Materialize: customer_dimension.customer_state, customer_dimension.customer_name
 | | |      Filter: (customer_dimension.customer_gender = &amp;#39;Male&amp;#39;)
 | | |      Filter: (customer_dimension.customer_state = ANY (ARRAY[&amp;#39;MA&amp;#39;, &amp;#39;NH&amp;#39;]))
 | | |      Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The query optimizer automatically picks the best projections, but without reasonably accurate statistics, the optimizer could choose a suboptimal projection or join order for a query. For details, see &lt;a href=&#34;../../../../../en/admin/collecting-db-statistics/&#34;&gt;Collecting Statistics&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;OpenText™ Analytics Database considers which projection to choose for a plan by considering the following aspects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How columns are joined in the query&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How the projections are grouped or sorted&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whether SQL analytic operations applied&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Any column information from a projection&#39;s storage on disk&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the database scans the possibilities for each plan, projections with the higher initial costs could end up in the final plan because they make joins cheaper. For example, a query can be answered with many possible plans, which the optimizer considers before choosing one of them. For efficiency, the optimizer uses sophisticated algorithms to prune intermediate partial plan fragments with higher cost. The optimizer knows that intermediate plan fragments might initially look bad (due to high storage access cost) but which produce excellent final plans due to other optimizations that it allows.&lt;/p&gt;
&lt;p&gt;If your statistics are up to date but the query still performs poorly, run the query through the Database Designer. For details, see &lt;a href=&#34;../../../../../en/admin/configuring-db/creating-db-design/general-design-settings/#Incremen&#34;&gt;Incremental Design&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;tips&#34;&gt;Tips&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To test different segmented projections, refer to the projection by name in the query.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For optimal performance, write queries so the columns are sorted the same way that the projection columns are sorted.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;../../../../../en/admin/managing-db/managing-workloads/workload-best-practices/reducing-query-run-time/#&#34;&gt;Reducing query run time&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../../../en/admin/configuring-db/creating-db-design/creating-custom-designs/#&#34;&gt;Creating custom designs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../../../en/admin/projections/#&#34;&gt;Projections&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Join path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/join-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/join-path/</guid>
      <description>
        
        
        &lt;p&gt;Just like a join query, which references two or more tables, the &lt;code&gt;Join&lt;/code&gt; step in a query plan has two input branches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The left input, which is the outer table of the join&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The right input, which is the inner table of the join&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the following query, the &lt;code&gt;T1&lt;/code&gt; table is the left input because it is on the left side of the JOIN keyword, and the &lt;code&gt;T2&lt;/code&gt; table is the right input, because it is on the right side of the JOIN keyword:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT * FROM T1 &lt;span class=&#34;code-input&#34;&gt;JOIN&lt;/span&gt; T2 ON T1.x = T2.x;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;outer-versus-inner-join&#34;&gt;Outer versus inner join&lt;/h2&gt;
&lt;p&gt;Query performance is better if the small table is used as the inner input to the join. The query optimizer automatically reorders the inputs to joins to ensure that this is the case unless the join in question is an outer join.

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

If the configuration parameter &lt;code&gt;EnableForceOuter&lt;/code&gt; is set to 1, you can control join inputs for specific tables through
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/statements/alter-statements/alter-table/#&#34;&gt;ALTER TABLE..FORCE OUTER&lt;/a&gt;&lt;/code&gt;. For details, see &lt;a href=&#34;../../../../../en/data-analysis/queries/joins/controlling-join-inputs/#&#34;&gt;Controlling join inputs&lt;/a&gt;.

&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;The following example shows a query and its plan for a left outer join:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT CD.annual_income,OSI.sale_date_key
-&amp;gt; FROM online_sales.online_sales_fact OSI
-&amp;gt; LEFT OUTER JOIN customer_dimension CD ON CD.customer_key = OSI.customer_key;
 Access Path:
 +-JOIN HASH [LeftOuter] [Cost: 4K, Rows: 5M] (PATH ID: 1)
 |  Join Cond: (CD.customer_key = OSI.customer_key)
 |  Materialize at Output: OSI.sale_date_key
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for OSI [Cost: 3K, Rows: 5M] (PATH ID: 2)
 | |      Projection: online_sales.online_sales_fact_DBD_12_seg_vmartdb_design_vmartdb_design
 | |      Materialize: OSI.customer_key
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for CD [Cost: 264, Rows: 50K] (PATH ID: 3)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | |      Materialize: CD.annual_income, CD.customer_key
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following example shows a query and its plan for a full outer join:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT CD.annual_income,OSI.sale_date_key
-&amp;gt; FROM online_sales.online_sales_fact OSI
-&amp;gt; FULL OUTER JOIN customer_dimension CD ON CD.customer_key = OSI.customer_key;
 Access Path:
 +-JOIN HASH [FullOuter] [Cost: 18K, Rows: 5M] (PATH ID: 1) Outer (RESEGMENT) Inner (FILTER)
 |  Join Cond: (CD.customer_key = OSI.customer_key)
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for OSI [Cost: 3K, Rows: 5M] (PATH ID: 2)
 | |      Projection: online_sales.online_sales_fact_DBD_12_seg_vmartdb_design_vmartdb_design
 | |      Materialize: OSI.sale_date_key, OSI.customer_key
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for CD [Cost: 264, Rows: 50K] (PATH ID: 3)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | |      Materialize: CD.annual_income, CD.customer_key
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;hash-and-merge-joins&#34;&gt;Hash and merge joins&lt;/h2&gt;
&lt;p&gt;OpenText™ Analytics Database has two join algorithms to choose from: merge join and hash join. The optimizer automatically chooses the most appropriate algorithm, given the query and projections in a system.&lt;/p&gt;
&lt;p&gt;For the following query, the optimizer chooses a hash join.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT CD.annual_income,OSI.sale_date_key
-&amp;gt; FROM online_sales.online_sales_fact OSI
-&amp;gt; INNER JOIN customer_dimension CD ON CD.customer_key = OSI.customer_key;
 Access Path:
 +-JOIN HASH [Cost: 4K, Rows: 5M] (PATH ID: 1)
 |  Join Cond: (CD.customer_key = OSI.customer_key)
 |  Materialize at Output: OSI.sale_date_key
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for OSI [Cost: 3K, Rows: 5M] (PATH ID: 2)
 | |      Projection: online_sales.online_sales_fact_DBD_12_seg_vmartdb_design_vmartdb_design
 | |      Materialize: OSI.customer_key
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for CD [Cost: 264, Rows: 50K] (PATH ID: 3)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | |      Materialize: CD.annual_income, CD.customer_key
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;alert admonition tip&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Tip&lt;/h4&gt;

If you get a hash join when you are expecting a merge join, it means that at least one of the projections is not sorted on the join column (for example, &lt;code&gt;customer_key&lt;/code&gt; in the preceding query). To facilitate a merge join, you might need to create different projections that are sorted on the join columns.

&lt;/div&gt;
&lt;p&gt;In the next example, the optimizer chooses a merge join. The optimizer&#39;s first pass performs a merge join because the inputs are presorted, and then it performs a hash join.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT count(*) FROM online_sales.online_sales_fact OSI
-&amp;gt; INNER JOIN customer_dimension CD ON CD.customer_key = OSI.customer_key
-&amp;gt; INNER JOIN product_dimension PD ON PD.product_key = OSI.product_key;
 Access Path:
 +-GROUPBY NOTHING [Cost: 8K, Rows: 1] (PATH ID: 1)
 |  Aggregates: count(*)
 |  Execute on: All Nodes
 | +---&amp;gt; JOIN HASH [Cost: 7K, Rows: 5M] (PATH ID: 2)
 | |      Join Cond: (PD.product_key = OSI.product_key)
 | |      Materialize at Input: OSI.product_key
 | |      Execute on: All Nodes
 | | +-- Outer -&amp;gt; JOIN MERGEJOIN(inputs presorted) [Cost: 4K, Rows: 5M] (PATH ID: 3)
 | | |      Join Cond: (CD.customer_key = OSI.customer_key)
 | | |      Execute on: All Nodes
 | | | +-- Outer -&amp;gt; STORAGE ACCESS for OSI [Cost: 3K, Rows: 5M] (PATH ID: 4)
 | | | |      Projection: online_sales.online_sales_fact_DBD_12_seg_vmartdb_design_vmartdb_design
 | | | |      Materialize: OSI.customer_key
 | | | |      Execute on: All Nodes
 | | | +-- Inner -&amp;gt; STORAGE ACCESS for CD [Cost: 132, Rows: 50K] (PATH ID: 5)
 | | | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | | | |      Materialize: CD.customer_key
 | | | |      Execute on: All Nodes
 | | +-- Inner -&amp;gt; STORAGE ACCESS for PD [Cost: 152, Rows: 60K] (PATH ID: 6)
 | | |      Projection: public.product_dimension_DBD_2_rep_vmartdb_design_vmartdb_design_node0001
 | | |      Materialize: PD.product_key
 | | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;inequality-joins&#34;&gt;Inequality joins&lt;/h2&gt;
&lt;p&gt;OpenText™ Analytics Database processes joins with equality predicates very efficiently. The query plan shows equality join predicates as join condition (&lt;code&gt;Join Cond&lt;/code&gt;).&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT CD.annual_income, OSI.sale_date_key
-&amp;gt; FROM online_sales.online_sales_fact OSI
-&amp;gt; INNER JOIN customer_dimension CD
-&amp;gt; ON CD.customer_key = OSI.customer_key;
 Access Path:
 +-JOIN HASH [Cost: 4K, Rows: 5M] (PATH ID: 1)
 |  Join Cond: (CD.customer_key = OSI.customer_key)
 |  Materialize at Output: OSI.sale_date_key
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for OSI [Cost: 3K, Rows: 5M] (PATH ID: 2)
 | |      Projection: online_sales.online_sales_fact_DBD_12_seg_vmartdb_design_vmartdb_design
 | |      Materialize: OSI.customer_key
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for CD [Cost: 264, Rows: 50K] (PATH ID: 3)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | |      Materialize: CD.annual_income, CD.customer_key
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, inequality joins are treated like cross joins and can run less efficiently, which you can see by the change in cost between the two queries:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT CD.annual_income, OSI.sale_date_key
-&amp;gt; FROM online_sales.online_sales_fact OSI
-&amp;gt; INNER JOIN customer_dimension CD
-&amp;gt; ON CD.customer_key &amp;lt; OSI.customer_key;
 Access Path:
 +-JOIN HASH [Cost: 98M, Rows: 5M] (PATH ID: 1)
 |  Join Filter: (CD.customer_key &amp;lt; OSI.customer_key)
 |  Materialize at Output: CD.annual_income
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for CD [Cost: 132, Rows: 50K] (PATH ID: 2)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | |      Materialize: CD.customer_key
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for OSI [Cost: 3K, Rows: 5M] (PATH ID: 3)
 | |      Projection: online_sales.online_sales_fact_DBD_12_seg_vmartdb_design_vmartdb_design
 | |      Materialize: OSI.sale_date_key, OSI.customer_key
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;event-series-joins&#34;&gt;Event series joins&lt;/h2&gt;
&lt;p&gt;Event series joins are denoted by the &lt;code&gt;INTERPOLATED&lt;/code&gt; path.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT * FROM hTicks h FULL OUTER JOIN aTicks a -&amp;gt; ON (h.time INTERPOLATE PREVIOUS
 Access Path:
 +-JOIN  (INTERPOLATED) [FullOuter] [Cost: 31, Rows: 4 (NO STATISTICS)] (PATH ID: 1)
   Outer (SORT ON JOIN KEY) Inner (SORT ON JOIN KEY)
 |  Join Cond: (h.&amp;#34;time&amp;#34; = a.&amp;#34;time&amp;#34;)
 |  Execute on: Query Initiator
 | +-- Outer -&amp;gt; STORAGE ACCESS for h [Cost: 15, Rows: 4 (NO STATISTICS)] (PATH ID: 2)
 | |      Projection: public.hTicks_node0004
 | |      Materialize: h.stock, h.&amp;#34;time&amp;#34;, h.price
 | |      Execute on: Query Initiator
 | +-- Inner -&amp;gt; STORAGE ACCESS for a [Cost: 15, Rows: 4 (NO STATISTICS)] (PATH ID: 3)
 | |      Projection: public.aTicks_node0004
 | |      Materialize: a.stock, a.&amp;#34;time&amp;#34;, a.price
 | |      Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: Path ID</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/path-id/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/path-id/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;code&gt;PATH ID&lt;/code&gt; is a unique identifier that OpenText™ Analytics Database assigns to each operation (path) within a query plan. The same identifier is shared by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../../../en/admin/managing-queries/query-plans/&#34;&gt;Query plans&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Join error messages&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System tables 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/system-tables/v-monitor-schema/execution-engine-profiles/#&#34;&gt;EXECUTION_ENGINE_PROFILES&lt;/a&gt;&lt;/code&gt; and 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/system-tables/v-monitor-schema/query-plan-profiles/#&#34;&gt;QUERY_PLAN_PROFILES&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Path IDs can help you trace issues to their root cause. For example, if a query returns a join error, preface the query with &lt;code&gt;EXPLAIN&lt;/code&gt; and look for &lt;code&gt;PATH ID &lt;/code&gt;&lt;em&gt;&lt;code&gt;n&lt;/code&gt;&lt;/em&gt; in the query plan to see which join in the query had the problem.&lt;/p&gt;
&lt;p&gt;For example, the following &lt;code&gt;EXPLAIN&lt;/code&gt; output shows the path ID for each path in the optimizer&#39;s query plan:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT * FROM fact JOIN dim ON x=y JOIN ext on y=z;
 Access Path:
 +-JOIN MERGEJOIN(inputs presorted) [Cost: 815, Rows: 10K (NO STATISTICS)] (&lt;span class=&#34;code-input&#34;&gt;PATH ID&lt;/span&gt;: 1)
 | Join Cond: (dim.y = ext.z)
 | Materialize at Output: fact.x
 | Execute on: All Nodes
 | +-- Outer -&amp;gt; JOIN MERGEJOIN(inputs presorted) [Cost: 408, Rows: 10K (NO STATISTICS)] (&lt;span class=&#34;code-input&#34;&gt;PATH ID&lt;/span&gt;: 2)
 | | Join Cond: (fact.x = dim.y)
 | | Execute on: All Nodes
 | | +-- Outer -&amp;gt; STORAGE ACCESS for fact [Cost: 202, Rows: 10K (NO STATISTICS)] (&lt;span class=&#34;code-input&#34;&gt;PATH ID&lt;/span&gt;: 3)
 | | | Projection: public.fact_super
 | | | Materialize: fact.x
 | | | Execute on: All Nodes
 | | +-- Inner -&amp;gt; STORAGE ACCESS for dim [Cost: 202, Rows: 10K (NO STATISTICS)] (&lt;span class=&#34;code-input&#34;&gt;PATH ID&lt;/span&gt;: 4)
 | | | Projection: public.dim_super
 | | | Materialize: dim.y
 | | | Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for ext [Cost: 202, Rows: 10K (NO STATISTICS)] (&lt;span class=&#34;code-input&#34;&gt;PATH ID&lt;/span&gt;: 5)
 | | Projection: public.ext_super
 | | Materialize: ext.z
 | | Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: Filter path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/filter-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/filter-path/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;code&gt;Filter&lt;/code&gt; step evaluates predicates on a single table. It accepts a set of rows, eliminates some of them (based on the criteria you provide in your query), and returns the rest. For example, the optimizer can filter local data of a join input that will be joined with another re-segmented join input.&lt;/p&gt;
&lt;p&gt;The following statement queries the &lt;code&gt;customer_dimension&lt;/code&gt; table and uses the WHERE clause to filter the results only for male customers in Massachusetts and New Hampshire.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;EXPLAIN SELECT
  CD.customer_name,
  CD.customer_state,
  AVG(CD.customer_age) AS avg_age,
  COUNT(*) AS count
FROM customer_dimension CD
WHERE CD.customer_state in (&amp;#39;MA&amp;#39;,&amp;#39;NH&amp;#39;) AND CD.customer_gender = &amp;#39;Male&amp;#39;
GROUP BY CD.customer_state, CD.customer_name;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The query plan output is as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; Access Path:
 +-GROUPBY HASH [Cost: 378, Rows: 544] (PATH ID: 1)
 |  Aggregates: sum_float(CD.customer_age), count(CD.customer_age), count(*)
 |  Group By: CD.customer_state, CD.customer_name
 |  Execute on: Query Initiator
 | +---&amp;gt; STORAGE ACCESS for CD [Cost: 372, Rows: 544] (PATH ID: 2)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | |      Materialize: CD.customer_state, CD.customer_name, CD.customer_age
 | |      Filter: (CD.customer_gender = &amp;#39;Male&amp;#39;)
 | |      Filter: (CD.customer_state = ANY (ARRAY[&amp;#39;MA&amp;#39;, &amp;#39;NH&amp;#39;]))
 | |      Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: GROUP BY paths</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/group-by-paths/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/group-by-paths/</guid>
      <description>
        
        
        &lt;p&gt;A GROUP BY operation has two algorithms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../../../en/admin/managing-queries/query-plans/query-plan-information-and-structure/group-by-paths/groupby-hash-query-plan/&#34;&gt;GROUPBY HASH&lt;/a&gt; input is not sorted by the group columns, so OpenText™ Analytics Database builds a hash table on those group columns in order to process the aggregates and group by expressions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../../../en/admin/managing-queries/query-plans/query-plan-information-and-structure/group-by-paths/groupby-pipelined-query-plan/&#34;&gt;GROUPBY PIPELINED&lt;/a&gt; requires that inputs be presorted on the columns specified in the group, which means that the database need only retain data in the current group in memory. GROUPBY PIPELINED operations are preferred because they are generally faster and require less memory than GROUPBY HASH. GROUPBY PIPELINED is especially useful for queries that process large numbers of high-cardinality group by columns or &lt;code&gt;DISTINCT&lt;/code&gt; aggregates.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If possible, the query optimizer chooses the faster algorithm GROUPBY PIPELINED over GROUPBY HASH.

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

For details, see &lt;a href=&#34;../../../../../en/data-analysis/query-optimization/group-by-queries/group-by-implementation-options/#&#34;&gt;GROUP BY implementation options&lt;/a&gt;.

&lt;/div&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Sort path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/sort-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/sort-path/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;code&gt;SORT&lt;/code&gt; operator sorts the data according to a specified list of columns. The EXPLAIN output indicates the sort expressions and if the sort order is ascending (ASC) or descending (DESC).&lt;/p&gt;
&lt;p&gt;For example, the following query plan shows the column list nature of the SORT operator:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;EXPLAIN SELECT
  CD.customer_name,
  CD.customer_state,
  AVG(CD.customer_age) AS avg_age,
  COUNT(*) AS count
FROM customer_dimension CD
WHERE CD.customer_state in (&amp;#39;MA&amp;#39;,&amp;#39;NH&amp;#39;)
  AND CD.customer_gender = &amp;#39;Male&amp;#39;
GROUP BY CD.customer_state, CD.customer_name
ORDER BY avg_age, customer_name;
 Access Path:
 +-SORT [Cost: 422, Rows: 544] (PATH ID: 1)
 |  Order: (&amp;lt;SVAR&amp;gt; / float8(&amp;lt;SVAR&amp;gt;)) ASC, CD.customer_name ASC
 |  Execute on: Query Initiator
 | +---&amp;gt; GROUPBY HASH [Cost: 378, Rows: 544] (PATH ID: 2)
 | |      Aggregates: sum_float(CD.customer_age), count(CD.customer_age), count(*)
 | |      Group By: CD.customer_state, CD.customer_name
 | |      Execute on: Query Initiator
 | | +---&amp;gt; STORAGE ACCESS for CD [Cost: 372, Rows: 544] (PATH ID: 3)
 | | |      Projection: public.customer_dimension_DBD_1_rep_vmart_vmart_node0001
 | | |      Materialize: CD.customer_state, CD.customer_name, CD.customer_age
 | | |      Filter: (CD.customer_gender = &amp;#39;Male&amp;#39;)
 | | |      Filter: (CD.customer_state = ANY (ARRAY[&amp;#39;MA&amp;#39;, &amp;#39;NH&amp;#39;]))
 | | |      Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you change the sort order to descending, the change appears in the query plan:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;EXPLAIN SELECT
  CD.customer_name,
  CD.customer_state,
  AVG(CD.customer_age) AS avg_age,
  COUNT(*) AS count
FROM customer_dimension CD
WHERE CD.customer_state in (&amp;#39;MA&amp;#39;,&amp;#39;NH&amp;#39;)
  AND CD.customer_gender = &amp;#39;Male&amp;#39;
GROUP BY CD.customer_state, CD.customer_name
ORDER BY avg_age DESC, customer_name;
 Access Path:
 +-SORT [Cost: 422, Rows: 544] (PATH ID: 1)
 |  Order: (&amp;lt;SVAR&amp;gt; / float8(&amp;lt;SVAR&amp;gt;)) DESC, CD.customer_name ASC
 |  Execute on: Query Initiator
 | +---&amp;gt; GROUPBY HASH [Cost: 378, Rows: 544] (PATH ID: 2)
 | |      Aggregates: sum_float(CD.customer_age), count(CD.customer_age), count(*)
 | |      Group By: CD.customer_state, CD.customer_name
 | |      Execute on: Query Initiator
 | | +---&amp;gt; STORAGE ACCESS for CD [Cost: 372, Rows: 544] (PATH ID: 3)
 | | |      Projection: public.customer_dimension_DBD_1_rep_vmart_vmart_node0001
 | | |      Materialize: CD.customer_state, CD.customer_name, CD.customer_age
 | | |      Filter: (CD.customer_gender = &amp;#39;Male&amp;#39;)
 | | |      Filter: (CD.customer_state = ANY (ARRAY[&amp;#39;MA&amp;#39;, &amp;#39;NH&amp;#39;]))
 | | |      Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: Limit path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/limit-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/limit-path/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;code&gt;LIMIT&lt;/code&gt; path restricts the number of result rows based on the LIMIT clause in the query. Using the &lt;code&gt;LIMIT&lt;/code&gt; clause in queries with thousands of rows might increase query performance.&lt;/p&gt;
&lt;p&gt;The optimizer pushes the &lt;code&gt;LIMIT&lt;/code&gt; operation as far down as possible in queries. A single &lt;code&gt;LIMIT&lt;/code&gt; clause in the query can generate multiple &lt;code&gt;Output Only&lt;/code&gt; plan annotations.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; =&amp;gt; EXPLAIN SELECT COUNT(DISTINCT annual_income) FROM customer_dimension LIMIT 10;
Access Path:
 +-SELECT  LIMIT 10 [Cost: 161, Rows: 10] (PATH ID: 0)
 |  Output Only: 10 tuples
 | +---&amp;gt; GROUPBY NOTHING [Cost: 161, Rows: 1] (PATH ID: 1)
 | |      Aggregates: count(DISTINCT customer_dimension.annual_income)
 | |      Output Only: 10 tuples
 | | +---&amp;gt; GROUPBY HASH (SORT OUTPUT) [Cost: 158, Rows: 10K] (PATH ID: 2)
 | | |      Group By: customer_dimension.annual_income
 | | | +---&amp;gt; STORAGE ACCESS for customer_dimension [Cost: 132, Rows: 50K] (PATH ID: 3)
 | | | |      Projection: public.customer_dimension_DBD_1_rep_vmartdb_design_vmartdb_design_node0001
 | | | |      Materialize: customer_dimension.annual_income
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: Data redistribution path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/data-redistribution-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/data-redistribution-path/</guid>
      <description>
        
        
        &lt;p&gt;The optimizer can redistribute join data in two ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Broadcasting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Resegmentation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;broadcasting&#34;&gt;Broadcasting&lt;/h2&gt;
&lt;p&gt;Broadcasting sends a complete copy of an intermediate result to all nodes in the cluster. Broadcast is used for joins in the following cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;One table is very small (usually the inner table) compared to the other.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OpenText™ Analytics Database can avoid other large upstream resegmentation operations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Outer join or subquery semantics require one side of the join to be replicated.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT * FROM T1 LEFT JOIN T2 ON T1.a &amp;gt; T2.y;
 Access Path:
 +-JOIN HASH [LeftOuter] [Cost: 40K, Rows: 10K (NO STATISTICS)] (PATH ID: 1) Inner (BROADCAST)
 |  Join Filter: (T1.a &amp;gt; T2.y)
 |  Materialize at Output: T1.b
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for T1 [Cost: 151, Rows: 10K (NO STATISTICS)] (PATH ID: 2)
 | |      Projection: public.T1_b0
 | |      Materialize: T1.a
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for T2 [Cost: 302, Rows: 10K (NO STATISTICS)] (PATH ID: 3)
 | |      Projection: public.T2_b0
 | |      Materialize: T2.x, T2.y
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;resegmentation&#34;&gt;Resegmentation&lt;/h2&gt;
&lt;p&gt;Resegmentation takes an existing projection or intermediate relation and resegments the data evenly across all cluster nodes. At the end of the resegmentation operation, every row from the input relation is on exactly one node. Resegmentation is the operation used most often for distributed joins in the database if the data is not already segmented for local joins. For more detail, see &lt;a href=&#34;../../../../../en/data-analysis/query-optimization/join-queries/identical-segmentation/#&#34;&gt;Identical segmentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE TABLE T1 (a INT, b INT) SEGMENTED BY HASH(a) ALL NODES;
=&amp;gt; CREATE TABLE T2 (x INT, y INT) SEGMENTED BY HASH(x) ALL NODES;
=&amp;gt; EXPLAIN SELECT * FROM T1 JOIN T2 ON T1.a = T2.y;

 ------------------------------ QUERY PLAN DESCRIPTION: ------------------------------
 Access Path:
 +-JOIN HASH [Cost: 639, Rows: 10K (NO STATISTICS)] (PATH ID: 1) Inner (RESEGMENT)
 |  Join Cond: (T1.a = T2.y)
 |  Materialize at Output: T1.b
 |  Execute on: All Nodes
 | +-- Outer -&amp;gt; STORAGE ACCESS for T1 [Cost: 151, Rows: 10K (NO STATISTICS)] (PATH ID: 2)
 | |      Projection: public.T1_b0
 | |      Materialize: T1.a
 | |      Execute on: All Nodes
 | +-- Inner -&amp;gt; STORAGE ACCESS for T2 [Cost: 302, Rows: 10K (NO STATISTICS)] (PATH ID: 3)
 | |      Projection: public.T2_b0
 | |      Materialize: T2.x, T2.y
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Analytic function path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/analytic-function-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/analytic-function-path/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database attempts to optimize multiple SQL-99 &lt;a href=&#34;../../../../../en/sql-reference/functions/analytic-functions/#&#34;&gt;Analytic functions&lt;/a&gt; from the same query by grouping them together in &lt;code&gt;Analytic Group&lt;/code&gt; areas.&lt;/p&gt;
&lt;p&gt;For each analytical group, the database performs a distributed sort and resegment of the data, if necessary.&lt;/p&gt;
&lt;p&gt;You can tell how many sorts and resegments are required based on the query plan.&lt;/p&gt;
&lt;p&gt;For example, the following query plan shows that the 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/functions/analytic-functions/first-value-analytic/#&#34;&gt;FIRST_VALUE&lt;/a&gt;&lt;/code&gt; and 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/functions/analytic-functions/last-value-analytic/#&#34;&gt;LAST_VALUE&lt;/a&gt;&lt;/code&gt; functions are in the same analytic group because their &lt;code&gt;OVER&lt;/code&gt; clause is the same. In contrast, &lt;code&gt;ROW_NUMBER()&lt;/code&gt; has a different &lt;code&gt;ORDER BY&lt;/code&gt; clause, so it is in a different analytic group. Because both groups share the same &lt;code&gt;PARTITION BY deal_stage&lt;/code&gt; clause, the data does not need to be resegmented between groups :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;EXPLAIN SELECT
  first_value(deal_size) OVER (PARTITION BY deal_stage
  ORDER BY deal_size),
  last_value(deal_size) OVER (PARTITION BY deal_stage
  ORDER BY deal_size),
  row_number() OVER (PARTITION BY deal_stage
  ORDER BY largest_bill_amount)
  FROM customer_dimension;

 Access Path:
 +-ANALYTICAL [Cost: 1K, Rows: 50K] (PATH ID: 1)
 |  Analytic Group
 |   Functions: row_number()
 |   Group Sort: customer_dimension.deal_stage ASC, customer_dimension.largest_bill_amount ASC NULLS LAST
 |  Analytic Group
 |   Functions: first_value(), last_value()
 |   Group Filter: customer_dimension.deal_stage
 |   Group Sort: customer_dimension.deal_stage ASC, customer_dimension.deal_size ASC NULL LAST
 |  Execute on: All Nodes
 | +---&amp;gt; STORAGE ACCESS for customer_dimension [Cost: 263, Rows: 50K]
         (PATH ID: 2)
 | |      Projection: public.customer_dimension_DBD_1_rep_vmart_vmart_node0001
 | |      Materialize: customer_dimension.largest_bill_amount,
          customer_dimension.deal_stage, customer_dimension.deal_size
 | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;a href=&#34;../../../../../en/data-analysis/sql-analytics/invoking-analytic-functions/#&#34;&gt;Invoking analytic functions&lt;/a&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Node down information</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/node-down-information/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/node-down-information/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database provides performance optimization when cluster nodes fail by distributing the work of the down nodes uniformly among available nodes throughout the cluster.&lt;/p&gt;
&lt;p&gt;When a node in your cluster is down, the query plan identifies which node the query will execute on. To help you quickly identify down nodes on large clusters, &lt;code&gt;EXPLAIN&lt;/code&gt; output lists up to six nodes, if the number of running nodes is less than or equal to six, and lists only down nodes if the number of running nodes is more than six.

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

The node that executes down node queries is not always the same one.

&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;The following table provides more detail:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;th &gt;
Node state&lt;/th&gt; 

&lt;th &gt;
EXPLAIN output&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
If all nodes are up, &lt;code&gt;EXPLAIN&lt;/code&gt; output indicates &lt;code&gt;All Nodes&lt;/code&gt;.&lt;/td&gt; 

&lt;td &gt;
&lt;code&gt;Execute on: All Nodes&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
If fewer than 6 nodes are up, &lt;code&gt;EXPLAIN&lt;/code&gt; lists up to six running nodes.&lt;/td&gt; 

&lt;td &gt;
&lt;code&gt;Execute on: [node_list].&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
If more than 6 nodes are up, &lt;code&gt;EXPLAIN&lt;/code&gt; lists only non-running nodes.&lt;/td&gt; 

&lt;td &gt;
&lt;code&gt;Execute on: All Nodes Except [node_list]&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
If the node list contains non-ephemeral nodes, the &lt;code&gt;EXPLAIN&lt;/code&gt; output indicates &lt;code&gt;All Permanent Nodes&lt;/code&gt;.&lt;/td&gt; 

&lt;td &gt;
&lt;code&gt;Execute on: All Permanent Nodes&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
If the path is being run on the query initiator, the &lt;code&gt;EXPLAIN&lt;/code&gt; output indicates &lt;code&gt;Query Initiator&lt;/code&gt;.&lt;/td&gt; 

&lt;td &gt;
&lt;code&gt;Execute on: Query Initiator&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;In the following example, the down node is &lt;code&gt;v_vmart_node0005&lt;/code&gt;, and the node &lt;code&gt;v_vmart_node0006&lt;/code&gt; will execute this run of the query.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT * FROM test;
QUERY PLAN
-----------------------------------------------------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT * FROM my1table;
Access Path:
+-STORAGE ACCESS for my1table [Cost: 10, Rows: 2] (PATH ID: 1)
| Projection: public.my1table_b0
| Materialize: my1table.c1, my1table.c2
| Execute on: All Except v_vmart_node0005
+-STORAGE ACCESS for my1table (REPLACEMENT FOR DOWN NODE) [Cost: 66, Rows: 2]
| Projection: public.my1table_b1
| Materialize: my1table.c1, my1table.c2
| Execute on: v_vmart_node0006
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;All Permanent Nodes&lt;/code&gt; output in the following example fragment denotes that the node list is for permanent (non-ephemeral) nodes only:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT * FROM my2table;
Access Path:
+-STORAGE ACCESS for my2table [Cost: 18, Rows:6 (NO STATISTICS)] (PATH ID: 1)
|  Projection: public.my2tablee_b0
|  Materialize: my2table.x, my2table.y, my2table.z
|  Execute on: All Permanent Nodes
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Admin: MERGE path</title>
      <link>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/merge-path/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/query-plans/query-plan-information-and-structure/merge-path/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database prepares an optimized query plan for a 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/statements/merge/#&#34;&gt;MERGE&lt;/a&gt;&lt;/code&gt; statement if the statement and its tables meet the criteria described in &lt;a href=&#34;../../../../../en/admin/working-with-native-tables/merging-table-data/merge-optimization/#&#34;&gt;MERGE optimization&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Use the 
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/statements/explain/#&#34;&gt;EXPLAIN&lt;/a&gt;&lt;/code&gt; keyword to determine whether the database can produce an optimized query plan for a given &lt;code&gt;MERGE&lt;/code&gt; statement. If optimization is possible, the &lt;code&gt;EXPLAIN&lt;/code&gt;-generated output contains a&lt;code&gt;[Semi]&lt;/code&gt; path, as shown in the following sample fragment:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
...
Access Path:
+-DML DELETE [Cost: 0, Rows: 0]
|  Target Projection: public.A_b1 (DELETE ON CONTAINER)
|  Target Prep:
|  Execute on: All Nodes
| +---&amp;gt; JOIN MERGEJOIN(inputs presorted) [Semi] [Cost: 6, Rows: 1 (NO STATISTICS)] (PATH ID: 1)
         Inner (RESEGMENT)
| |      Join Cond: (A.a1 = VAL(2))
| |      Execute on: All Nodes
| | +-- Outer -&amp;gt; STORAGE ACCESS for A [Cost: 2, Rows: 2 (NO STATISTICS)] (PATH ID: 2)
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Conversely, if the database cannot create an optimized plan, &lt;code&gt;EXPLAIN&lt;/code&gt;-generated output contains &lt;code&gt;RightOuter&lt;/code&gt; path:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
...
Access Path: +-DML MERGE
 |  Target Projection: public.locations_b1
 |  Target Projection: public.locations_b0
 |  Target Prep:
 |  Execute on: All Nodes
 | +---&amp;gt; JOIN MERGEJOIN(inputs presorted) [RightOuter] [Cost: 28, Rows: 3 (NO STATISTICS)] (PATH ID: 1) Outer (RESEGMENT) Inner (RESEGMENT)
 | |      Join Cond: (locations.user_id = VAL(2)) AND (locations.location_x = VAL(2)) AND (locations.location_y = VAL(2))
 | |      Execute on: All Nodes
 | | +-- Outer -&amp;gt; STORAGE ACCESS for &amp;lt;No Alias&amp;gt; [Cost: 15, Rows: 2 (NO STATISTICS)] (PATH ID: 2)
...
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
  </channel>
</rss>
