Plan optimization guidelines are applied during the cost-based
phase of optimization, where access methods, join methods, join order,
and other details of the execution plan for the statement are determined.
Plan optimization guidelines need not specify all aspects
of an execution plan. Unspecified aspects of the execution plan are
determined by the optimizer in a cost-based fashion.
There are two categories of plan optimization guidelines:
- accessRequest – An access request specifies an access method
for satisfying a table reference in a statement.
- joinRequest – A join request specifies a method and sequence
for performing a join operation. Join requests are composed of access
or other join requests.
Access request optimization guidelines correspond to the
optimizer's data access methods, such as table scan, index scan,
and list prefetch. Join request guidelines correspond to the optimizer's
join methods, such as nested-loop join, hash join, and merge join.
Each access request and join request is represented by a corresponding
access request element and join request element in the statement optimization
guideline schema.
The following example illustrates an index scan access request,
as represented by the IXSCAN access request element. This particular
request specifies that the optimizer is to use the I_SUPPKEY index
to access the SUPPLIERS table in the main subselect of the statement.
The optional INDEX attribute identifies the desired index. The TABLE
attribute identifies the table reference to which the access request
is applied. A TABLE attribute must identify the target table reference
using its exposed name, which in this example is the correlation name
S.
SQL statement:
select s.s_name, s.s_address, s.s_phone, s.s_comment
from "Samp".parts, "Samp".suppliers s, "Samp".partsupp ps
where p_partkey = ps.ps_partkey and
s.s_suppkey = ps.ps_suppkey and
p_size = 39 and
p_type = 'BRASS' and
s.s_nation in ('MOROCCO', 'SPAIN') and
ps.ps_supplycost = (select min(ps1.ps_supplycost)
from "Samp".partsupp ps1, "Samp".suppliers s1
where "Samp".parts.p_partkey = ps1.ps_partkey and
s1.s_suppkey = ps1.ps_suppkey and
s1.s_nation = s.s_nation)
order by s.s_name
Optimization guideline:
<OPTGUIDELINES>
<IXSCAN TABLE='S' INDEX='I_SUPPKEY'/>
</OPTGUIDELINES>
The following index scan access request element specifies that
the optimizer is to use index access to the PARTS table in the main
subselect of the statement. The optimizer will choose the index in
a cost-based fashion, because there is no INDEX attribute. The TABLE
attribute uses the qualified table name to refer to the target table
reference, because there is no associated correlation name.
<OPTGUIDELINES>
<IXSCAN TABLE='"Samp".PARTS'/>
</OPTGUIDELINES>
The following list prefetch access request is represented by the
LPREFETCH access request element. This particular request specifies
that the optimizer is to use the I_SNATION index to access the SUPPLIERS
table in the nested subselect of the statement. The TABLE attribute
uses the correlation name S1, because that is the exposed name identifying
the SUPPLIERS table reference in the nested subselect.
<OPTGUIDELINES>
<LPREFETCH TABLE='S1' INDEX='I_SNATION'/>
</OPTGUIDELINES>
The following index scan access request element specifies that
the optimizer is to use the I_SNAME index to access the SUPPLIERS
table in the main subselect. The FIRST attribute specifies that this
table is to be the first table that is accessed in the join sequence
chosen for the corresponding FROM clause. The FIRST attribute can
be added to any access or join request; however, there can be at most
one access or join request with the FIRST attribute referring to tables
in the same FROM clause.
SQL statement:
select s.s_name, s.s_address, s.s_phone, s.s_comment
from "Samp".parts, "Samp".suppliers s, "Samp".partsupp ps
where p_partkey = ps.ps_partkey
s.s_suppkey = ps.ps_suppkey and
p_size = 39 and
p_type = 'BRASS' and
s.s_nation in ('MOROCCO', 'SPAIN') and
ps.ps_supplycost = (select min(ps1.ps_supplycost)
from "Samp".partsupp ps1, "Samp".suppliers s1
where "Samp".parts.p_partkey = ps1.ps_partkey and
s1.s_suppkey = ps1.ps_suppkey and
s1.s_nation = s.s_nation)
order by s.s_name
optimize for 1 row
Optimization guidelines:
<OPTGUIDELINES>
<IXSCAN TABLE='S' INDEX='I_SNAME' FIRST='TRUE'/>
</OPTGUIDELINES>
The following example illustrates how multiple access requests
are passed in a single statement optimization guideline. The TBSCAN
access request element represents a table scan access request. This
particular request specifies that the SUPPLIERS table in the nested
subselect is to be accessed using a full table scan. The LPREFETCH
access request element specifies that the optimizer is to use the
I_SUPPKEY index during list prefetch index access to the SUPPLIERS
table in the main subselect.
<OPTGUIDELINES>
<TBSCAN TABLE='S1'/>
<LPREFETCH TABLE='S' INDEX='I_SUPPKEY'/>
</OPTGUIDELINES>
The following example illustrates a nested-loop join request, as
represented by the NLJOIN join request element. In general, a join
request element contains two child elements. The first child element
represents the desired outer input to the join operation, and the
second child element represents the desired inner input to the join
operation. The child elements can be access requests, other join requests,
or combinations of access and join requests. In this example, the
first IXSCAN access request element specifies that the PARTS table
in the main subselect is to be the outer table of the join operation.
It also specifies that PARTS table access be performed using an index
scan. The second IXSCAN access request element specifies that the
PARTSUPP table in the main subselect is to be the inner table of the
join operation. It, too, specifies that the table is to be accessed
using an index scan.
<OPTGUIDELINES>
<NLJOIN>
<IXSCAN TABLE='"Samp".Parts'/>
<IXSCAN TABLE="PS"/>
</NLJOIN>
</OPTGUIDELINES>
The following example illustrates a hash join request, as represented
by the HSJOIN join request element. The ACCESS access request element
specifies that the SUPPLIERS table in the nested subselect is to be
the outer table of the join operation. This access request element
is useful in cases where specifying the join order is the primary
objective. The IXSCAN access request element specifies that the PARTSUPP
table in the nested subselect is to be the inner table of the join
operation, and that the optimizer is to choose an index scan to access
that table.
<OPTGUIDELINES>
<HSJOIN>
<ACCESS TABLE='S1'/>
<IXSCAN TABLE='PS1'/>
</HSJOIN>
</OPTGUIDELINES>
The following example illustrates how larger join requests can
be constructed by nesting join requests. The example includes a merge
join request, as represented by the MSJOIN join request element. The
outer input of the join operation is the result of joining the PARTS
and PARTSUPP tables of the main subselect, as represented by the NLJOIN
join request element. The inner input of the join request element
is the SUPPLIERS table in the main subselect, as represented by the
IXSCAN access request element.
<OPTGUIDELINES>
<MSJOIN>
<NLJOIN>
<IXSCAN TABLE='"Samp".Parts'/>
<IXSCAN TABLE="PS"/>
</NLJOIN>
<IXSCAN TABLE='S'/>
</MSJOIN>
</OPTGUIDELINES>
If a join request is to be valid, all access request elements that
are nested either directly or indirectly inside of it must reference
tables in the same FROM clause of the optimized statement.
Optimization
guidelines for MQT matching
Users can override the optimizer's
decision and force it to choose specific materialized query tables
(MQTs) with the MQTENFORCE element. The MQTENFORCE element, can be
specified at both the global and statement profile level, is used
with one of the following attributes:
- NAME
- specifies the partial or fully qualified name of MQT to choose
- TYPE
- specifies a group of MQTs by their types. Possible values are:
- NORMAL: all non-replicated MQTs
- REPLICATED: all replicated MQTs
- ALL: all MQTs
The following example illustrates an example
of a guideline that enforces all replicated MQTs, as well as, the
SAMP.PARTSMQT:
<OPTGUIDELINES>
<MQTENFORCE NAME='SAMP.PARTSMQT'/>
<MQTENFORCE TYPE='REPLICATED'/>
</OPTGUIDELINES>
Note: If you specify more than one
attribute at a time, only the first one will be used. So in the following
example
<MQTENFORCE NAME='SAMP.PARTSMQT' TYPE='REPLICATED'/>
Only
PARTSMQT MQT will be enforced