<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – Creating directed queries</title>
    <link>/en/admin/managing-queries/directed-queries/creating-directed-queries/</link>
    <description>Recent content in Creating directed queries on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/admin/managing-queries/directed-queries/creating-directed-queries/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Admin: Optimizer-generated directed queries</title>
      <link>/en/admin/managing-queries/directed-queries/creating-directed-queries/optimizer-generated-directed-queries/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/directed-queries/creating-directed-queries/optimizer-generated-directed-queries/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a name=&#34;CREATE_DIRECTED_QUERY_OPTIMIZER&#34;&gt;&lt;/a&gt;&lt;a href=&#34;../../../../../en/sql-reference/statements/create-statements/create-directed-query/&#34;&gt;CREATE DIRECTED QUERY OPTIMIZER&lt;/a&gt; passes an input query to the optimizer, which generates an annotated query from its own query plan. It then pairs the input and annotated queries and saves them as a directed query. This directed query can be used to handle other queries that are identical except for the predicate strings on which query results are filtered.&lt;/p&gt;
&lt;p&gt;You can use optimizer-generated directed queries to capture query plans before you upgrade. Doing so can be especially useful if you detect diminished performance of a given query after the upgrade. In this case, you can use the corresponding directed query to recreate an earlier query plan, and compare its performance to the plan generated by the current optimizer.&lt;/p&gt;
&lt;p&gt;You can also create multiple optimizer-generated directed queries from the most frequently executed queries, by invoking the meta-function &lt;a href=&#34;../../../../../en/sql-reference/functions/directed-queries-functions/save-plans/#&#34;&gt;SAVE_PLANS&lt;/a&gt;. For details, see &lt;a href=&#34;#Bulk-Creation_of_Directed_Queries&#34;&gt;Bulk-Creation of Directed Queries&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;The following SQL statements create and activate the directed query &lt;code&gt;findEmployeesCityJobTitle_OPT&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; CREATE DIRECTED QUERY OPTIMIZER &amp;#39;findEmployeesCityJobTitle_OPT&amp;#39;
     SELECT employee_first_name, employee_last_name FROM public.employee_dimension
     WHERE employee_city=&amp;#39;Boston&amp;#39; and job_title=&amp;#39;Cashier&amp;#39; ORDER BY employee_last_name, employee_first_name;
CREATE DIRECTED QUERY

=&amp;gt; ACTIVATE DIRECTED QUERY findEmployeesCityJobTitle_OPT;
ACTIVATE DIRECTED QUERY
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this directed query plan is activated, the optimizer uses it to generate a query plan for all subsequent invocations of this input query, and others like it. You can view the optimizer-generated annotated query by calling &lt;a href=&#34;../../../../../en/sql-reference/statements/get-directed-query/#&#34;&gt;GET DIRECTED QUERY&lt;/a&gt; or querying system table &lt;a href=&#34;../../../../../en/sql-reference/system-tables/v-catalog-schema/directed-queries/#&#34;&gt;DIRECTED_QUERIES&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT input_query, annotated_query FROM V_CATALOG.DIRECTED_QUERIES
      WHERE query_name = &amp;#39;findEmployeesCityJobTitle_OPT&amp;#39;;
-[ RECORD 1 ]---+----------------------------------------------------------------------------
input_query     | SELECT employee_dimension.employee_first_name, employee_dimension.employee_last_name FROM public.employee_dimension
WHERE ((employee_dimension.employee_city = &amp;#39;Boston&amp;#39;::varchar(6) &lt;span class=&#34;code-input&#34;&gt;/*+:v(1)*/&lt;/span&gt;) AND (employee_dimension.job_title = &amp;#39;Cashier&amp;#39;::varchar(7) &lt;span class=&#34;code-input&#34;&gt;/*+:v(2)*&lt;/span&gt;/))
ORDER BY employee_dimension.employee_last_name, employee_dimension.employee_first_name
annotated_query | SELECT /*+verbatim*/ employee_dimension.employee_first_name AS employee_first_name, employee_dimension.employee_last_name AS employee_last_name FROM public.employee_dimension AS employee_dimension/*+projs(&amp;#39;public.employee_dimension&amp;#39;)*/
WHERE (employee_dimension.employee_city = &amp;#39;Boston&amp;#39;::varchar(6) &lt;span class=&#34;code-input&#34;&gt;/*+:v(1)*/&lt;/span&gt;) AND (employee_dimension.job_title = &amp;#39;Cashier&amp;#39;::varchar(7) &lt;span class=&#34;code-input&#34;&gt;/*+:v(2)&lt;/span&gt;*/)
ORDER BY 2 ASC, 1 ASC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the annotated query includes the following hints:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/language-elements/hints/verbatim/#&#34;&gt;/*&amp;#43;verbatim*/&lt;/a&gt;&lt;/code&gt; specifies to execute the annotated query exactly as written and produce a query plan accordingly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href=&#34;../../../../../en/sql-reference/language-elements/hints/projs/#&#34;&gt;/*&amp;#43;projs(&amp;#39;public.Emp_Dimension&amp;#39;)*/&lt;/a&gt;&lt;/code&gt; directs the optimizer to create a query plan that uses the projection &lt;code&gt;public.Emp_Dimension&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../../../../en/admin/managing-queries/directed-queries/ignoring-constants-directed-queries/&#34;&gt;&lt;code&gt;/*+:v(&lt;/code&gt;&lt;em&gt;&lt;code&gt;n&lt;/code&gt;&lt;/em&gt;&lt;code&gt;)*/&lt;/code&gt;&lt;/a&gt; (alias of &lt;code&gt;/*+IGNORECONST(&lt;/code&gt;&lt;em&gt;&lt;code&gt;n&lt;/code&gt;&lt;/em&gt;&lt;code&gt;)*/&lt;/code&gt;) is included several times in the annotated and input queries. These hints qualify two constants in the query predicates: &lt;code&gt;Boston&lt;/code&gt; and &lt;code&gt;Cashier&lt;/code&gt;. Each &lt;code&gt;:v&lt;/code&gt; hint has an integer argument &lt;em&gt;&lt;code&gt;n&lt;/code&gt;&lt;/em&gt; that pairs corresponding constants in the input and annotated query queries: &lt;code&gt;*+:v(1)*/&lt;/code&gt; for &lt;code&gt;Boston&lt;/code&gt;, and &lt;code&gt;/*+:v(2)*/&lt;/code&gt; for &lt;code&gt;Cashier&lt;/code&gt;. The hints tell the optimizer to disregard these constants when it decides whether to apply this directed query to other input queries that are similar. Thus, ignore constant hints can let you use the same directed query for different input queries.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following query uses different values for the columns &lt;code&gt;employee_city&lt;/code&gt; and &lt;code&gt;job_title&lt;/code&gt;, but is otherwise identical to the original input query of directed query &lt;code&gt;EmployeesCityJobTitle_OPT&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT employee_first_name, employee_last_name FROM public.employee_dimension
     WHERE employee_city = &amp;#39;San Francisco&amp;#39; and job_title = &amp;#39;Branch Manager&amp;#39; ORDER BY employee_last_name, employee_first_name;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the directed query &lt;code&gt;EmployeesCityJobTitle_OPT&lt;/code&gt; is active, the optimizer can use it for this query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT employee_first_name, employee_last_name FROM employee_dimension
      WHERE employee_city=&amp;#39;San Francisco&amp;#39; AND job_title=&amp;#39;Branch Manager&amp;#39; ORDER BY employee_last_name, employee_first_name;
 ...
 ------------------------------
 QUERY PLAN DESCRIPTION:
 ------------------------------
 EXPLAIN SELECT employee_first_name, employee_last_name FROM employee_dimension WHERE employee_city=&amp;#39;San Francisco&amp;#39; AND job_title=&amp;#39;Branch Manager&amp;#39; ORDER BY employee_last_name, employee_first_name;

 The following active directed query(query name: findEmployeesCityJobTitle_OPT) is being executed:
 SELECT /*+verbatim*/  employee_dimension.employee_first_name, employee_dimension.employee_last_name
 FROM public.employee_dimension employee_dimension/*+projs(&amp;#39;public.employee_dimension&amp;#39;)*/
 WHERE ((employee_dimension.employee_city = &amp;#39;San Francisco&amp;#39;::varchar(13)) AND (employee_dimension.job_title = &amp;#39;Branch Manager&amp;#39;::varchar(14)))
 ORDER BY employee_dimension.employee_last_name, employee_dimension.employee_first_name

 Access Path:
 +-SORT [Cost: 222, Rows: 10K (NO STATISTICS)] (PATH ID: 1)
 |  Order: employee_dimension.employee_last_name ASC, employee_dimension.employee_first_name ASC
 |  Execute on: All Nodes
 | +---&amp;gt; STORAGE ACCESS for employee_dimension [Cost: 60, Rows: 10K (NO STATISTICS)] (PATH ID: 2)
 | |      Projection: public.employee_dimension_super
 | |      Materialize: employee_dimension.employee_first_name, employee_dimension.employee_last_name
 | |      Filter: (employee_dimension.employee_city = &amp;#39;San Francisco&amp;#39;)
 | |      Filter: (employee_dimension.job_title = &amp;#39;Branch Manager&amp;#39;)
 | |      Execute on: All Nodes
 ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a name=&#34;Bulk-Creation_of_Directed_Queries&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;bulk-creation-of-directed-queries&#34;&gt;Bulk-creation of directed queries&lt;/h2&gt;
&lt;p&gt;The meta-function &lt;a href=&#34;../../../../../en/sql-reference/functions/directed-queries-functions/save-plans/#&#34;&gt;SAVE_PLANS&lt;/a&gt; lets you create multiple optimizer-generated directed queries from the most frequently executed queries. SAVE_PLANS works as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Iterates over all queries in the data collector table &lt;code&gt;dc_requests_issued&lt;/code&gt; and selects the most-frequently requested queries, up to the maximum specified by its &lt;em&gt;&lt;code&gt;query-budget&lt;/code&gt;&lt;/em&gt; argument. If the meta-function&#39;s &lt;em&gt;&lt;code&gt;since-date&lt;/code&gt;&lt;/em&gt; argument is also set, then SAVE_PLANS iterates only over queries that were issued on or after the specified date.&lt;/p&gt;
&lt;p&gt;As SAVE_PLANS iterates over &lt;code&gt;dc_requests_issued&lt;/code&gt;, it tests queries against various restrictions. In general, directed queries support only SELECT statements as input. Within this broad requirement, input queries are subject to other &lt;a href=&#34;../../../../../en/admin/managing-queries/directed-queries/directed-query-restrictions/&#34;&gt;restrictions&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Calls &lt;a name=&#34;CREATE_DIRECTED_QUERY_OPTIMIZER&#34;&gt;&lt;/a&gt;CREATE DIRECTED QUERY OPTIMIZER on all qualifying input queries, which creates a directed query for each unique input query as described &lt;a href=&#34;#CREATE_DIRECTED_QUERY_OPTIMIZER&#34;&gt;above&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Saves metadata on the new set of directed queries to system table &lt;a href=&#34;../../../../../en/sql-reference/system-tables/v-catalog-schema/directed-queries/#&#34;&gt;DIRECTED_QUERIES&lt;/a&gt;, where all directed queries of that set share the same &lt;code&gt;SAVE_PLANS_VERSION&lt;/code&gt; integer. This integer is computed from the highest &lt;code&gt;SAVE_PLANS_VERSION&lt;/code&gt; + 1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can later use &lt;code&gt;SAVE_PLANS_VERSION&lt;/code&gt; identifiers to bulk &lt;a href=&#34;../../../../../en/sql-reference/statements/activate-directed-query/&#34;&gt;activate&lt;/a&gt;, &lt;a href=&#34;../../../../../en/sql-reference/statements/deactivate-directed-query/&#34;&gt;deactivate&lt;/a&gt;, and &lt;a href=&#34;../../../../../en/sql-reference/statements/drop-statements/drop-directed-query/&#34;&gt;drop&lt;/a&gt; directed queries. For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT save_plans (40);
                                                 save_plans
-------------------------------------------------------------------------------------------------------------
 9 directed query supported queries out of 40 most frequently run queries were saved under the save_plans_version 3.

To view the saved queries, run:

        SELECT * FROM directed_queries WHERE save_plans_version = &amp;#39;3&amp;#39;;

To drop the saved queries, run:

        DROP DIRECTED QUERY WHERE save_plans_version = &amp;#39;3&amp;#39;;
(1 row)

=&amp;gt; SELECT input_query::VARCHAR(60) FROM directed_queries WHERE save_plans_version = 3 AND input_query ILIKE &amp;#39;%line_search%&amp;#39;;
                         input_query
--------------------------------------------------------------
 SELECT public.line_search_logistic2(udtf1.deviance, udtf1.G
 SELECT public.line_search_logistic2(udtf1.deviance, udtf1.G
(2 rows)

=&amp;gt; ACTIVATE DIRECTED QUERY WHERE save_plans_version = 3 AND input_query ILIKE &amp;#39;%line_search%&amp;#39;;
ACTIVATE DIRECTED QUERY
=&amp;gt; SELECT query_name, input_query::VARCHAR(60), is_active FROM directed_queries WHERE save_plans_version = 3 AND input_query ILIKE &amp;#39;%line_search%&amp;#39;;
       query_name       |                         input_query                          | is_active
------------------------+--------------------------------------------------------------+-----------
 save_plans_nolabel_3_3 | SELECT public.line_search_logistic2(udtf1.deviance, udtf1.G  | t
 save_plans_nolabel_6_3 | SELECT public.line_search_logistic2(udtf1.deviance, udtf1.G  | t
(2 rows)
&lt;/code&gt;&lt;/pre&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;

&lt;p&gt;&lt;code&gt;query_name&lt;/code&gt; values are concatenated from the following strings:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;save_plans_&lt;span class=&#34;code-variable&#34;&gt;query-label&lt;/span&gt;_&lt;span class=&#34;code-variable&#34;&gt;query-number&lt;/span&gt;_&lt;span class=&#34;code-variable&#34;&gt;save-plans-version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;query-label&lt;/code&gt;&lt;/em&gt; is a &lt;a href=&#34;../../../../../en/sql-reference/language-elements/hints/label/#&#34;&gt;LABEL&lt;/a&gt; hint embedded in the input query associated with this directed query. If theinput query contains no label, then this string is set to &lt;code&gt;nolabel&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;query-number&lt;/code&gt;&lt;/em&gt; is an integer in a continuous sequence between 0 and &lt;em&gt;&lt;code&gt;budget-query&lt;/code&gt;&lt;/em&gt;, which uniquely identifies this directed query from others in the same SAVE_PLANS-generated set.&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;code-variable&#34;&gt;[save-plans-version](/en/sql-reference/system-tables/v-catalog-schema/directed-queries/#SAVE_PLANS_VERSION)&lt;/span&gt; identifies the set of directed queries to which this directed query belongs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/div&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Custom directed queries</title>
      <link>/en/admin/managing-queries/directed-queries/creating-directed-queries/custom-directed-queries/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/directed-queries/creating-directed-queries/custom-directed-queries/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;../../../../../en/sql-reference/statements/create-statements/create-directed-query/&#34;&gt;CREATE DIRECTED QUERY CUSTOM&lt;/a&gt; specifies an annotated query and pairs it to an input query previously saved by &lt;a href=&#34;../../../../../en/sql-reference/statements/save-query/#&#34;&gt;SAVE QUERY&lt;/a&gt;. You must issue both statements in the same user session.&lt;/p&gt;
&lt;p&gt;For example, you might want a query to use a specific projection:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Specify the query with SAVE QUERY:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SAVE QUERY SELECT employee_first_name, employee_last_name FROM employee_dimension
    WHERE employee_city=&amp;#39;Boston&amp;#39; AND job_title=&amp;#39;Cashier&amp;#39;;
SAVE QUERY
&lt;/code&gt;&lt;/pre&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;

The input query that you supply to SAVE QUERY only supports the &lt;a href=&#34;../../../../../en/admin/managing-queries/directed-queries/ignoring-constants-directed-queries/#&#34;&gt;:v&lt;/a&gt; hint.

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a custom directed query with CREATE DIRECTED QUERY CUSTOM, which specifies an annotated query and associates it with the saved query. The annotated query includes a &lt;code&gt;/*+projs*/&lt;/code&gt; hint, which instructs the optimizer to use the projection &lt;code&gt;public.emp_dimension_unseg&lt;/code&gt; when users call the saved query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; CREATE DIRECTED QUERY CUSTOM &amp;#39;findBostonCashiers_CUSTOM&amp;#39;
   SELECT employee_first_name, employee_last_name
   FROM employee_dimension /*+Projs(&amp;#39;public.emp_dimension_unseg&amp;#39;)*/
   WHERE employee_city=&amp;#39;Boston&amp;#39; AND job_title=&amp;#39;Cashier&amp;#39;;
CREATE DIRECTED QUERY
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;admonition caution&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Caution&lt;/h4&gt;

OpenText™ Analytics Database associates a saved query and annotated query without checking whether the input and annotated queries are compatible. Be careful to sequence SAVE QUERY and CREATE DIRECTED QUERY CUSTOM statements so the saved and directed queries are correctly matched.

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Activate the directed query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ACTIVATE DIRECTED QUERY findBostonCashiers_CUSTOM;
ACTIVATE DIRECTED QUERY
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After activation, the optimizer uses this directed query to generate a query plan for all subsequent invocations of its input query. The following &lt;a href=&#34;../../../../../en/sql-reference/statements/explain/#&#34;&gt;EXPLAIN&lt;/a&gt; output verifies the optimizer&#39;s use of this directed query and the projection it specifies:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; EXPLAIN SELECT employee_first_name, employee_last_name FROM employee_dimension
   WHERE employee_city=&amp;#39;Boston&amp;#39; AND job_title=&amp;#39;Cashier&amp;#39;;

QUERY PLAN
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT employee_first_name, employee_last_name FROM employee_dimension where employee_city=&amp;#39;Boston&amp;#39; AND job_title=&amp;#39;Cashier&amp;#39;;

 &lt;span class=&#34;code-input&#34;&gt;The following active directed query(query name: findBostonCashiers_CUSTOM) is being executed:&lt;/span&gt;
 SELECT employee_dimension.employee_first_name, employee_dimension.employee_last_name
  FROM public.employee_dimension&lt;span class=&#34;code-input&#34;&gt;/*+Projs(&#39;public.emp_dimension_unseg&#39;)*/&lt;/span&gt;
  WHERE ((employee_dimension.employee_city = &amp;#39;Boston&amp;#39;::varchar(6)) AND (employee_dimension.job_title = &amp;#39;Cashier&amp;#39;::varchar(7)))

 Access Path:
 +-STORAGE ACCESS for employee_dimension [Cost: 158, Rows: 10K (NO STATISTICS)] (PATH ID: 1)
 |  Projection: public.emp_dimension_unseg
 |  Materialize: employee_dimension.employee_first_name, employee_dimension.employee_last_name
 |  Filter: (employee_dimension.employee_city = &amp;#39;Boston&amp;#39;)
 |  Filter: (employee_dimension.job_title = &amp;#39;Cashier&amp;#39;)
 |  Execute on: Query Initiator
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;../../../../../en/admin/managing-queries/directed-queries/rewriting-queries/#Rewritin&#34;&gt;Rewriting Join Queries&lt;/a&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Admin: Using optimizer-generated and custom directed queries together</title>
      <link>/en/admin/managing-queries/directed-queries/creating-directed-queries/using-optimizer-generated-and-custom-directed-queries-together/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/admin/managing-queries/directed-queries/creating-directed-queries/using-optimizer-generated-and-custom-directed-queries-together/</guid>
      <description>
        
        
        &lt;p&gt;You can use the annotated SQL that the optimizer creates as the basis for creating your own custom directed queries. This approach can be especially useful in evaluating the plan that the optimizer creates to handle a given query, and testing plan modifications.&lt;/p&gt;
&lt;p&gt;For example, you might want to modify how the optimizer implements the following query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT COUNT(customer_name) Total, customer_region Region
    FROM (store_sales s JOIN customer_dimension c ON c.customer_key = s.customer_key)
    JOIN product_dimension p ON s.product_key = p.product_key
    WHERE p.category_description ilike &amp;#39;%Medical%&amp;#39;
      AND p.product_description ilike &amp;#39;%antibiotics%&amp;#39;
      AND c.customer_age &amp;lt;= 30 AND YEAR(s.sales_date)=2017
    GROUP BY customer_region;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you run EXPLAIN on this query, you discover that the optimizer uses projection &lt;code&gt;customers_proj_age&lt;/code&gt; for the &lt;code&gt;customer_dimension&lt;/code&gt; table. This projection is sorted on column &lt;code&gt;customer_age&lt;/code&gt;. Consequently, the optimizer hash-joins the tables &lt;code&gt;store_sales&lt;/code&gt; and &lt;code&gt;customer_dimension&lt;/code&gt; on &lt;code&gt;customer_key&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After analyzing &lt;code&gt;customer_dimension&lt;/code&gt; table data, you observe that most customers are under 30, so it makes more sense to use projection &lt;code&gt;customer_proj_id&lt;/code&gt; for the &lt;code&gt;customer_dimension&lt;/code&gt; table, which is sorted on &lt;code&gt;customer_key&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;You can create a directed query that encapsulates this change as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Obtain optimizer-generated annotations on the query with EXPLAIN ANNOTATED:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; \o annotatedQuery
=&amp;gt; EXPLAIN ANNOTATED SELECT COUNT(customer_name) Total, customer_region Region
     FROM (store_sales s JOIN customer_dimension c ON c.customer_key = s.customer_key)
     JOIN product_dimension p ON s.product_key = p.product_key
     WHERE p.category_description ilike &amp;#39;%Medical%&amp;#39;
       AND p.product_description ilike &amp;#39;%antibiotics%&amp;#39;
       AND c.customer_age &amp;lt;= 30 AND YEAR(s.sales_date)=2017
     GROUP BY customer_region;
=&amp;gt; \o
=&amp;gt; \! cat annotatedQuery
...
SELECT /*+syntactic_join,verbatim*/ count(c.customer_name) AS Total, c.customer_region AS Region
 FROM ((public.store_sales AS s/*+projs(&amp;#39;public.store_sales_super&amp;#39;)*/
    JOIN /*+Distrib(L,B),JType(H)*/ public.customer_dimension AS c/*+projs(&amp;#39;public.customers_proj_age&amp;#39;)*/
      ON (c.customer_key = s.customer_key))
    JOIN /*+Distrib(L,B),JType(M)*/ public.product_dimension AS p/*+projs(&amp;#39;public.product_dimension&amp;#39;)*/
      ON (s.product_key = p.product_key))
 WHERE ((date_part(&amp;#39;year&amp;#39;::varchar(4), (s.sales_date)::timestamp(0)))::int = 2017)
     AND (c.customer_age &amp;lt;= 30)
     AND ((p.category_description)::varchar(32) ~~* &amp;#39;%Medical%&amp;#39;::varchar(9))
     AND (p.product_description ~~* &amp;#39;%antibiotics%&amp;#39;::varchar(13))
 GROUP BY  /*+GByType(Hash)*/ 2
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify the annotated query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
SELECT /*+syntactic_join,verbatim*/ count(c.customer_name) AS Total, c.customer_region AS Region
 FROM ((public.store_sales AS s/*+projs(&amp;#39;public.store_sales_super&amp;#39;)*/
    JOIN /*+Distrib(L,B),JType(H)*/ public.customer_dimension AS c/*+projs(&amp;#39;public.customer_proj_id&amp;#39;)*/
      ON (c.customer_key = s.customer_key))
    JOIN /*+Distrib(L,B),JType(H)*/ public.product_dimension AS p/*+projs(&amp;#39;public.product_dimension&amp;#39;)*/
      ON (s.product_key = p.product_key))
 WHERE ((date_part(&amp;#39;year&amp;#39;::varchar(4), (s.sales_date)::timestamp(0)))::int = 2017)
     AND (c.customer_age &amp;lt;= 30)
     AND ((p.category_description)::varchar(32) ~~* &amp;#39;%Medical%&amp;#39;::varchar(9))
     AND (p.product_description ~~* &amp;#39;%antibiotics%&amp;#39;::varchar(13))
 GROUP BY  /*+GByType(Hash)*/ 2
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the modified annotated query to create the desired directed query:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Save the desired input query with &lt;a href=&#34;../../../../../en/sql-reference/statements/save-query/#&#34;&gt;SAVE QUERY&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; SAVE QUERY SELECT COUNT(customer_name) Total, customer_region Region
    FROM (store_sales s JOIN customer_dimension c ON c.customer_key = s.customer_key)
    JOIN product_dimension p ON s.product_key = p.product_key
    WHERE p.category_description ilike &amp;#39;%Medical%&amp;#39;
      AND p.product_description ilike &amp;#39;%antibiotics%&amp;#39;
      AND c.customer_age &amp;lt;= 30 AND YEAR(s.sales_date)=2017
    GROUP BY customer_region;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a custom directed query that associates the saved input query with the modified annotated query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; CREATE DIRECTED QUERY CUSTOM &amp;#39;getCustomersUnder31&amp;#39;
   SELECT /*+syntactic_join,verbatim*/ count(c.customer_name) AS Total, c.customer_region AS Region
 FROM ((public.store_sales AS s/*+projs(&amp;#39;public.store_sales_super&amp;#39;)*/
    JOIN /*+Distrib(L,B),JType(H)*/ public.customer_dimension AS c/*+projs(&amp;#39;public.customer_proj_id&amp;#39;)*/
      ON (c.customer_key = s.customer_key))
    JOIN /*+Distrib(L,B),JType(H)*/ public.product_dimension AS p/*+projs(&amp;#39;public.product_dimension&amp;#39;)*/
      ON (s.product_key = p.product_key))
 WHERE ((date_part(&amp;#39;year&amp;#39;::varchar(4), (s.sales_date)::timestamp(0)))::int = 2017)
     AND (c.customer_age &amp;lt;= 30)
     AND ((p.category_description)::varchar(32) ~~* &amp;#39;%Medical%&amp;#39;::varchar(9))
     AND (p.product_description ~~* &amp;#39;%antibiotics%&amp;#39;::varchar(13))
 GROUP BY  /*+GByType(Hash)*/ 2;
CREATE DIRECTED QUERY
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Activate this directed query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ACTIVATE DIRECTED QUERY getCustomersUnder31;
ACTIVATE DIRECTED QUERY
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the optimizer processes a query that matches this directed query&#39;s input query, it uses the directed query&#39;s annotated query to generate a query plan:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT COUNT(customer_name) Total, customer_region Region
     FROM (store_sales s JOIN customer_dimension c ON c.customer_key = s.customer_key)
     JOIN product_dimension p ON s.product_key = p.product_key
     WHERE p.category_description ilike &amp;#39;%Medical%&amp;#39;
       AND p.product_description ilike &amp;#39;%antibiotics%&amp;#39;
       AND c.customer_age &amp;lt;= 30 AND YEAR(s.sales_date)=2017
     GROUP BY customer_region;

 The following active directed query(query name: getCustomersUnder31) is being executed:
...
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
  </channel>
</rss>
