最適化ガイドラインでの表参照の形成

表参照 という語は、SQL ステートメント内またはビュー定義内のすべての表、ビュー、表式、または別名が参照する表を意味します。 最適化ガイドラインは、元のステートメントにある直接的な名前を使用するか、あるいは最適化ステートメントの表参照に関連付けられた固有な相関名を使用して、表参照を識別することができます。

直接的な名前の連続である拡張名は、ビューに組み込まれている表参照を一意的に識別するのに役立ちます。 別名は、最適化ガイドラインの表参照として使用できません。 そのような場合には、表参照のガイドラインは無視されることになります。 ステートメント全体のコンテキストで固有ではない直接的な名前や拡張名を識別する最適化ガイドラインは、未確定と見なされ、適用されません。 さらに、同一の表参照を識別する複数の最適化ガイドラインが存在する場合は、その表参照を識別するすべての最適化ガイドラインが競合していると見なされ、適用されません。 照会のトランスフォーメーションが行われる可能性があると、直接的な名前または拡張名が最適化の間もそのまま存在するという保証はありません。そのため、そのような表参照を識別するすべてのガイドラインが無視されます。

索引名は、一部の最適化ガイドライン・エレメントの INDEX 属性または IXNAME 属性で指定します。 索引名は、非修飾名でなければなりません。

元のステートメントにある直接的な名前を使用した表参照の識別

表参照を、表の直接的な名前を使用して識別します。 直接的な名前は、SQL ステートメント内で表が修飾されるときと同じ要領で指定されます。

SQL ID を指定するときの規則が、最適化ガイドラインの TABLE 属性の値にも適用されます。 TABLE 属性の値は、ステートメントの直接的な名前とそれぞれ比較されます。 この Db2® リリースでは、単一の一致のみが許可されます。 TABLE 属性値がスキーマ修飾されている場合、その値は、同等の直接的な修飾表名すべてと一致します。 TABLE 属性値が修飾されていない場合、その値は、同等の相関名または直接的な表名すべてと一致します。 そのため、TABLE 属性値は、そのステートメントで有効なデフォルトのスキーマによって暗黙的に修飾されたものと見なされます。 これらの概念について、以下に例を示します。 ステートメントは、デフォルト・スキーマ Sampを使用して最適化されると想定します。
   select s_name, s_address, s_phone, s_comment
     from parts, suppliers, partsupp ps
     where p_partkey = ps.ps_partkey and
       s.s_suppkey = ps.ps_suppkey and
       p_size = 39 and
       p_type = 'BRASS'

ステートメント内の表参照を識別する TABLE 属性値には、「Samp」が含まれます。「PARTS」、「PARTS」、「Parts」(ID は区切り文字で区切られていないため、大文字に変換されます)。 ステートメントで表参照を識別できない TABLE 属性値には、「Samp2」、「SUPPLIERS」、「PARTSUPP」(直接的な名前ではない)、および「Samp」があります。「PARTS」(ID Samp は区切り文字で区切る必要があります。そうしないと、大文字に変換されます)。

直接的な名前は、元のステートメント、ビュー、SQL 関数、またはトリガーにあるどの表参照をターゲットにする際にも使用できます。

元のステートメントにある直接的な名前を使用したビューの表参照の識別

以下の例に示されているように、最適化ガイドラインでは、拡張構文を使用してビューに組み込まれた表参照を識別することができます。
   create view "Rick".v1 as
     (select * from employee a where salary > 50000)

   create view "Gustavo".v2 as
     (select * from "Rick".v1
        where deptno in ('52', '53', '54')

   select * from "Gustavo".v2 a
     where v2.hire_date > '01/01/2004'

   <OPTGUIDELINES>
     <IXSCAN TABLE='A/"Rick".V1/A'/>
   </OPTGUIDELINES>
IXSCAN アクセス要求エレメントは、"Gustavo".V2 および "Rick".V1 の各ビューに組み込まれた EMPLOYEE 表参照に、索引スキャンを使用するように指定します。 ビューの表参照を識別するための拡張構文は、スラッシュ文字によって分離された一連の直接的な名前です。 TABLE 属性 A/"Rick".V1/A の値は、拡張構文の例です。 シーケンスの最後の直接的な名前 (A) は、最適化ガイドラインのターゲットである表参照を識別します。 シーケンスの最初の直接的な名前 (A) は、元のステートメントで直接的に参照されるビューを識別します。 中間の直接的な 1 つまたは複数の名前 ("Rick".V1) は、直接的なビュー参照からターゲット表参照へのパスの、ビュー参照に関係しています。 最適化ガイドラインから直接的な名前への参照に関する規則 (前のセクションで説明されている) は、拡張構文の各ステップに適用されます。

ビューの EMPLOYEE 表参照の直接的な名前が、ステートメントによって直接的または間接的に参照されるすべての表に関して固有であったなら、拡張名前構文は必要ありませんでした。

拡張構文は、元のステートメント、SQL 関数、またはトリガーのどの表参照をターゲットにする際にも使用できます。

最適化ステートメントの相関名を使用した表参照の識別

最適化ガイドラインでは、最適化ステートメントの表参照に関連付けられた固有の相関名を使用して表参照を識別することもできます。 最適化ステートメントは、元のステートメントと意味的に同等なバージョンで、最適化の照会書き直しのフェーズで決定されるものです。 最適化ステートメントは、Explain 表から取得できます。 最適化ステートメントの表参照の識別には、最適化ガイドラインの TABID 属性が使用されます。

Original statement:

   select s.s_name, s.s_address, s.s_phone, s.s_comment
     from sm_samp.parts p, sm_samp.suppliers s, sm_samp.partsupp ps
     where p_partkey = ps.ps_partkey and
       s.s_suppkey = ps.ps_suppkey and
       p.p_size = 39 and
       p.p_type = 'BRASS' and
       s.s_nation in ('MOROCCO', 'SPAIN') and
       ps.ps_supplycost = (select min(ps1.ps_supplycost)
                             from sm_samp.partsupp ps1, sm_samp.suppliers s1
                             where p.p_partkey = ps1.ps_partkey and
                               s1.s_suppkey = ps1.ps_suppkey and
                               s1.s_nation = s.s_nation)

   <OPTGUIDELINES>
     <HSJOIN>
       <TBSCAN TABLE='S1'/>
       <IXSCAN TABID='Q2'/>
     </HSJOIN>
   </OPTGUIDELINES>

Optimized statement:

   select q6.s_name as "S_NAME", q6.s_address as "S_ADDRESS",
       q6.s_phone as "S_PHONE", q6.s_comment as "S_COMMENT"
     from (select min(q4.$c0)
             from (select q2.ps_supplycost
                     from sm_samp.suppliers as q1, sm_samp.partsupp as q2
                     where q1.s_nation = 'MOROCCO' and
                       q1.s_suppkey = q2.ps_suppkey and
                       q7.p_partkey = q2.ps_partkey
                     ) as q3
             ) as q4, sm_samp.partsupp as q5, sm_samp.suppliers as q6,
                 sm_samp.parts as q7
     where p_size = 39 and
       q5.ps_supplycost = q4.$c0 and
       q6.s_nation in ('MOROCCO', 'SPAIN') and
       q7.p_type = 'BRASS' and
       q6.s_suppkey = q5.ps_suppkey and
       q7.p_partkey = q5.ps_partkey
この最適化ガイドラインは、ハッシュ結合要求を示しています。ここで、TBSCAN アクセス要求エレメントによって指定されているように、ネストされた副選択内の SUPPLIERS 表が外部表です。また、IXSCAN アクセス要求エレメントによって指定されているように、ネストされた副選択内の PARTSUPP 表が内部表です。 TBSCAN アクセス要求エレメントは、TABLE 属性を使用して SUPPLIERS 表参照を識別しますが、その際、元のステートメントにある対応する直接的な名前を使用します。 一方、IXSCAN アクセス要求エレメントは、TABID 属性を使用して PARTSUPP 表参照を識別しますが、その際、最適化ステートメントの表参照に関連付けられた固有の相関名を使用します。
1 つの最適化ガイドラインに TABLE 属性と TABID 属性の両方が指定されている場合は、両方の属性が同じ表参照を識別している必要があります。そうでない場合、その最適化ガイドラインは無視されます。
注: 現在のところ、 Db2 製品の新規リリースにアップグレードする際に、最適化されたステートメント内の相関名が安定する保証はありません。

未確定表参照

最適化ガイドラインが複数の直接的な名前または拡張名と一致する場合、その最適化ガイドラインは無効であると見なされ、適用されません。

   create view v1 as
     (select * from employee 
        where salary > (select avg(salary) from employee)

   select * from v1
     where deptno in ('M62', 'M63')

   <OPTGUIDE>
     <IXSCAN TABLE='V1/EMPLOYEE'/>
   </OPTGUIDE>
直接的な名前 EMPLOYEE がビュー V1 の定義内で固有でないため、オプティマイザーは、IXSCAN アクセス要求を未確定と見なします。

このあいまいさをなくすためには、固有の相関名を使用するようにビューを書き直すか、TABID 属性を使用することができます。 最適化ステートメントの相関名はすべて固有であるため、TABID 属性で識別された表参照は未確定になることがありません。

競合する最適化ガイドライン

同じ表参照を複数の最適化ガイドラインで識別することはできません。

以下に例を示します。
   <OPTGUIDELINES>
     <IXSCAN TABLE='"Samp".PARTS' INDEX='I_PTYPE'/>
     <IXSCAN TABLE='"Samp".PARTS' INDEX='I_SIZE'/>
   </OPTGUIDELINES>
各 IXSCAN エレメントは、「Samp」を参照します。メイン副選択内の PARTS 表。

複数のガイドラインが同じ表を参照する場合は、最初のガイドラインだけが適用されます。それ以外のガイドラインはすべて無視され、エラーが戻ります。

各照会の述部レベルで使用可能にできるのは、INLIST2JOIN 照会再書き込み要求エレメント 1 つだけです。以下の例は、サポートされていない照会書き直し最適化ガイドラインを示しています。ここでは、2 つの IN-LIST 述部が述部レベルで有効にされています。 両方のガイドラインが無視され、警告が戻されます。
   <OPTGUIDELINES>
     <INLIST2JOIN TABLE='P' COLUMN='P_SIZE'/>
	   <INLIST2JOIN TABLE='P' COLUMN='P_TYPE'/>
   </OPTGUIDELINES>