LoginSignup
0
0

More than 5 years have passed since last update.

Cognos Framework Managerのリレーションの設定でのパフォーマンスチューニング

Posted at

概要

へえ~、これ知らんかったわ、でもこれ、結構重要じゃね。
と、最近思ったシリーズです。

「こいつこんなのも知らんのか」と、スキルレベルがバレてしまいますが、気にせず投稿します。

今回の「へえ~」は、Framework Managerのリレーションのプロパティの一つである「(DQM)フィルター・タイプ」です。
004.JPG

動きの説明

前述のSLS_PRODUCT_DIMとSLS_SALES_FACTを、PRODUCT_KEYでリレーション張っただけのモデルをパッケージとして発行し、こんなレポートを作ってみます。
例のプロパティは、とりあえずデフォルトの「なし」です。
PRODUCT_KEYはSLS_PRODUCT_DIM表から、QUANTITYはSLS_SALES_FACT表から取ってます。
005.JPG

クエリーはこんな感じで、PRODUCT_KEYにIN句で、30010と30200にフィルターをかけています。
ちなみに、PRODUCT_KEYは、30001から30274まであります。
006.JPG

レポート実行すると、こんな結果です。
001.JPG

(DQM)フィルター・タイプ = なし の場合
どの設定でも、出力される結果は同じです。

発行されるクエリーが異なり、この設定では以下のクエリーが発行されます。
ちなみに、Db2側でアクセスパスを取得したところ、コストは 2248.25 でした。

SELECT
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" AS "PRODUCT_KEY", 
    SUM("SLS_SALES_FACT"."QUANTITY") AS "QUANTITY"
FROM
    "GOSALESDW"."SLS_PRODUCT_DIM" "SLS_PRODUCT_DIM"
        INNER JOIN "GOSALESDW"."SLS_SALES_FACT" "SLS_SALES_FACT"
        ON "SLS_PRODUCT_DIM"."PRODUCT_KEY" = "SLS_SALES_FACT"."PRODUCT_KEY" 
WHERE 
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" IN ( 
        '30010', 
        '30200' ) 
GROUP BY 
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" FOR FETCH ONLY;

(DQM)フィルター・タイプ = 指定の値の間 の場合
この設定では以下のクエリーが発行されます。
WHERE句で、SLS_SALES_FACTの方にもBETWEEN 30010 AND 30200という絞込みが入っているのがわかりますね。
つまり、IN句の指定値の中で、最小値の30010と最大値の30200でBETWEENしています。
これにより、SLS_PRODUCT_DIMの結果データと、SLS_SALES_FACTの結果データを結合(INNER JOIN)する前に、SLS_SALES_FACT側のデータが絞り込まれているので、結合の対象となるデータ量を少なくすることができます。
アクセスパスのコストは、残念ながらちょっと上がって 2331.92 でした。

SELECT
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" AS "PRODUCT_KEY", 
    SUM("SLS_SALES_FACT"."QUANTITY") AS "QUANTITY"
FROM
    "GOSALESDW"."SLS_PRODUCT_DIM" "SLS_PRODUCT_DIM"
        INNER JOIN "GOSALESDW"."SLS_SALES_FACT" "SLS_SALES_FACT"
        ON "SLS_PRODUCT_DIM"."PRODUCT_KEY" = "SLS_SALES_FACT"."PRODUCT_KEY" 
WHERE 
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" IN ( 
        '30010', 
        '30200' ) AND
    "SLS_SALES_FACT"."PRODUCT_KEY" BETWEEN 30010 AND 30200 
GROUP BY 
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" FOR FETCH ONLY;

(DQM)フィルター・タイプ = テーブル の場合
この設定では以下のクエリーが発行されます。
さすがに最後にもってくるからには、良い結果なんだろうと想像されたと思いますが、その通りです。
WHERE句で、SLS_SALES_FACTの方にもPRODUCT_KEYが 30010 と 30200という絞込みが入っているのがわかりますね。
つまり、IN句の指定値で絞込みしています。
これにより、SLS_PRODUCT_DIMの結果データと、SLS_SALES_FACTの結果データを結合(INNER JOIN)する前に、SLS_SALES_FACT側のデータが絞り込まれているので、結合の対象となるデータ量を少なくすることができます。
アクセスパスのコストは、ちゃんと落ちが付いて良かった 1346.86 でした。

SELECT
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" AS "PRODUCT_KEY", 
    SUM("SLS_SALES_FACT"."QUANTITY") AS "QUANTITY"
FROM
    "GOSALESDW"."SLS_PRODUCT_DIM" "SLS_PRODUCT_DIM"
        INNER JOIN "GOSALESDW"."SLS_SALES_FACT" "SLS_SALES_FACT"
        ON "SLS_PRODUCT_DIM"."PRODUCT_KEY" = "SLS_SALES_FACT"."PRODUCT_KEY" 
WHERE 
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" IN ( 
        '30010', 
        '30200' ) AND
    "SLS_SALES_FACT"."PRODUCT_KEY" IN ( 
        SELECT
            "joinKeyQuery"."joinKey1"
        FROM
            (
            VALUES 
                (30010), 
                (30200)
            ) "joinKeyQuery"("joinKey1") ) 
GROUP BY 
    "SLS_PRODUCT_DIM"."PRODUCT_KEY" FOR FETCH ONLY;

という感じですね。

フィルターで指定される値が大量にある場合は「指定の値の間」、少ない場合は「テーブル」を指定するのが正解なのかな。
この設定、これまで気にした事無かったですが、なんか普通にリレーションの使い方考えて、「指定の値の間」か「テーブル」か、どっちかに設定しておいた方がパフォーマンス良くなるんじゃないか、と思い、今度実戦で使ってみようと思う次第です。
皆様も是非使ってみて頂き、知見が得られたらフィードバック頂けると幸いです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0