Cognos Framework Managerのリレーションの設定でのパフォーマンスチューニング
概要
へえ~、これ知らんかったわ、でもこれ、結構重要じゃね。
と、最近思ったシリーズです。
「こいつこんなのも知らんのか」と、スキルレベルがバレてしまいますが、気にせず投稿します。
今回の「へえ~」は、Framework Managerのリレーションのプロパティの一つである「(DQM)フィルター・タイプ」です。
動きの説明
前述のSLS_PRODUCT_DIMとSLS_SALES_FACTを、PRODUCT_KEYでリレーション張っただけのモデルをパッケージとして発行し、こんなレポートを作ってみます。
例のプロパティは、とりあえずデフォルトの「なし」です。
PRODUCT_KEYはSLS_PRODUCT_DIM表から、QUANTITYはSLS_SALES_FACT表から取ってます。
クエリーはこんな感じで、PRODUCT_KEYにIN句で、30010と30200にフィルターをかけています。
ちなみに、PRODUCT_KEYは、30001から30274まであります。
(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;
という感じですね。
フィルターで指定される値が大量にある場合は「指定の値の間」、少ない場合は「テーブル」を指定するのが正解なのかな。
この設定、これまで気にした事無かったですが、なんか普通にリレーションの使い方考えて、「指定の値の間」か「テーブル」か、どっちかに設定しておいた方がパフォーマンス良くなるんじゃないか、と思い、今度実戦で使ってみようと思う次第です。
皆様も是非使ってみて頂き、知見が得られたらフィードバック頂けると幸いです!
Author And Source
この問題について(Cognos Framework Managerのリレーションの設定でのパフォーマンスチューニング), 我々は、より多くの情報をここで見つけました https://qiita.com/shinyama/items/737faa7f7838a1954779著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .