3.4.6 WORK TABLE SUBQの対策
- 〈この項の構成〉
(1) WORK TABLE SUBQとは
WORK TABLE SUBQとは,限定述語およびIN述語に対する表副問合せに適用される副問合せの実行方式です。まず,副問合せの選択式の値を求めて,作業表を作成します(図中の1)。次に,外側の問合せを検索し1行検索するごとに,副問合せの結果と突き合わせて探索条件を評価します(図中の2)。このため,処理効率が悪いです。
(2) 確認方法
WORK TABLE SUBQの確認方法を次に示します。
-
HiRDB SQL Tuning Advisorの場合
アクセスパス情報の「副問合せ実行方式」に「WORK TABLE SUBQ」と表示されます。WORK TABLE SUBQの出力例を次に示します。
図3‒30 HiRDB SQL Tuning Advisorの出力例 -
UAP統計レポートの場合
アクセスパス情報の「Sub Query Type」に「WORK TABLE SUBQ」と表示されます。WORK TABLE SUBQの出力例を次に示します。
図3‒31 UAP統計レポートの出力例
(3) 対策方法
適用条件を確認して,次のどちらかの方法で対策してください。
項番 |
対策方法 |
適用条件 |
---|---|---|
1 |
インデクスを追加または変更して,副問合せの実行方式をWORK TABLE ATS SUBQに変更してください。 |
|
2 |
EXISTS述語を使ったSQL文への変更と,インデクスを追加または変更して,副問合せの実行方式をNESTED LOOPS ROW VALUE SUBQに変更してください。 |
|
(a) WORK TABLE ATS SUBQへの変更
インデクスを追加または変更して,副問合せの実行方式をWORK TABLE ATS SUBQに変更します。これによって,外側の問合せのインデクスを使用して副問合せの結果との条件を評価するため,効率がよいです。また,副問合せのヒット件数分の値を探索条件に指定し,外側の問合せの表を検索するため,副問合せのヒット件数が少ない場合に効果があります。
次の個所に表示された列を外側の問合せで使用しているインデクスの構成列に加えることで,WORK TABLE ATS SUBQに変更できます。外側の問合せがTABLE SCANの場合は,次の個所に表示された列にインデクスを追加してください。
-
HiRDB SQL Tuning Advisorの場合
アクセスパス情報の外側の問合せの「IF-THEN条件」で,副問合せ(SUBQ)の結果と条件評価している列をインデクスの構成列に追加してください。
図3‒32 HiRDB SQL Tuning Advisorの出力例 -
UAP統計レポートの場合
アクセスパス情報の外側の問合せの「IfThenCnd」で,副問合せ(SUBQ)の結果と条件評価している列をインデクスの構成列に追加してください。
図3‒33 UAP統計レポートの出力例
- [注意事項]
-
インデクスに構成列を追加する場合は,探索条件の指定方法を考慮して,構成列の順序を決定してください。詳細は,マニュアル「HiRDB Version 9 システム導入・設計ガイド」の「インデクス構成列の検討」を参照してください。
(b) NESTED LOOPS ROW VALUE SUBQへの変更
EXISTS述語使ったSQL文に変更して,副問合せの実行方式をNESTED LOOPS ROW VALUE SUBQに変更します。これによって,副問合せのインデクスを使用して,外側の問合せの結果との条件を評価するため,効率がよいです。また,この方法では,外側の問合せのヒット件数分,副問合せを実行するため,外側の問合せのヒット件数が少ない場合に効果があります。SQL文の変更方法の例を次に示します。
述語 |
変更前 |
変更後 |
---|---|---|
IN述語(IN) |
SELECT * FROM T1 WHERE T1.C1 IN (SELECT T2.C1 FROM T2 WHERE T2.C2 = ?) AND T1.C3>? |
SELECT * FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2 = ? AND T1.C1 = T2.C1) AND T1.C3>? |
IN述語(NOT IN) |
SELECT * FROM T1 WHERE T1.C1 NOT IN (SELECT T2.C1 FROM T2 WHERE T2.C2 = ?) AND T1.C3>? |
SELECT * FROM T1 WHERE NOT EXISTS(SELECT * FROM T2 WHERE T2.C2 = ? AND T1.C1 = T2.C1) AND T1.C3>? |
限定述語(=ANYまたは=SOME) |
SELECT * FROM T1 WHERE T1.C1 = ANY(SELECT T2.C1 FROM T2 WHERE T2.C2 = ?) AND T1.C3>? |
SELECT * FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2 = ? AND T1.C1 = T2.C1) AND T1.C3>? |
また,副問合せのすべての探索条件が1つのインデクスで評価できるようにしてください。1つのインデクスで評価できているか確認する方法は,「効率の悪いNESTED LOOPS JOIN」の手順を参照してください。
IN述語の例題のSQL文について,対策後のアクセスパスの出力例を次に示します。この例では,副問合せ側の表T2の列C2とC1に複数列インデクスを定義します。