アプリケーション パフォーマンスの最適化
はじめに
一般に、小規模または中規模の QlikView アプリケーションでは、アプリケーションの設計中にパフォーマンスを心配する必要はありません。データが多くなるに従って、アプリケーションの設計が不十分だと、時間とメモリの制約が目立つ場合があります。簡単な設計の変更によって大幅にパフォーマンスを向上させることが可能です。この付録では、ありがちな落とし穴を指摘し、その改善法を提案します。
一般に、"問題" をアプリケーション オブジェクトからスクリプト ドリブン データベースに移動すると、パフォーマンスが向上します。多くの場合、これには長所と短所があります。応答時間は向上しますが、アドホックな機能は低下します。以下の推奨事項は、すべての場合に適しているわけではありません。アプリケーションの状態が全般的によくなる場合、または違いがあまりない場合に使用してください。
以下に、問題に対応するために適用する方法の例を示します。問題について説明し、便利な QlikView 機能を紹介します。どの方法が最適かを推奨することはできませんが、重要度が高い順に例を説明します。
If ( Condition(Text),....)
一般に、テキストを比較する句は時間がかかります。解決方法としては、autonumber などを使用してテキストを数値にマップしたり (前のセクションの例を参照)、スクリプト内でテストします。
テキスト文字列のテストは、数値のテストより遅くなります。次の数式について考えます。
If (Alfa= ‘ABC’, ‘ABC’, left (Alfa, 2))
柔軟性を損なわずにスクリプト内で直接テストを実行できます。
Load
*,
If (Alfa = ‘ABC’, 1, 0) as Flag
resident table_1 ;
数式は次のようになります。
If ( Flag = 1,’ABC’, left (Alfa, 2))
テストはかなり簡単になります。
Sum ( If (Condition, ‘FieldName’...))
ここでは、集計がテーブルの軸とは無関係で、結果がテーブルの複数の軸に分散します。この問題には、スクリプト内でテストを行い、テーブル内で集計するか、スクリプト内ですべての演算を行うことで対処できます。これには、interval match、[group by、peek、if....then....else などの多くの方法があります。
この例では、"Condition" のテストと結果の集計の 2 つの手順を行います。前の例に集計を追加します。
Sum ( If (Alfa= ‘ABC’, Num*1.25 , Num) )
Load
*,
If (Alfa = ‘ABC’, 1, 0) as Flag
resident table_1 ;
数式は次のようになります。
Sum ( If ( Flag = 1, Num* 1.25 , Num ) )
集計は、スクリプト内で次のように直接実行することもできます。
table_2:
Load
*,
If (Alfa = ‘ABC’, 1, 0) as Flag
resident table_1 ;
table_3:
Load
Alfa,
If ( Flag = 1, Num* 1.25 , Num ) as NewNum
resident table_2 ;
table_4:
Load
Alfa,
Sum( NewNum ) as SumNum
resident table_3
group by Alfa ;
If ( Condition, Sum(‘FieldName’)..)
この構文は、前の例との違いを強調する目的でここに入れました。この集計は完全にコンテキスト目的です。一般にはパフォーマンスの問題が発生しません。
If ( Condition1, Sum(‘FieldName’), If (Condition2, Sum(‘FieldName’)... ... ..
ネストされた If...then else... ロジックは、概念的には簡単ですが、しばしば対処しにくい問題の元になります。数百のネスト レベルが含まれていた例もあります。これはメモリと CPU の両方を集中的に使用します。この "Condition" は、変換によって置き換えが可能なことがよくあります。典型的な例は、quantity*price の集計です。price は変数です。これは、"拡張 intervalmatch" で処理できます。たとえば、次の 2 つの条件 “A AND B” が満たされる場合、このテストは 1 つの条件 "C" に置き換えることができます。
例:
sum((GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY)
Replaces
sum
If((GAC12_EFCT_DT<= GIV23_REJ_DT and
GAC12_EXPIRE_DT>GIV23_REJ_DT) and
(GAC15_EFCT_DT<= GIV23_REJ_DT and GAC15_EXPIRE_DT>GIV23_REJ_DT),
GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,
Null()))
および
sum
If(GAC12_EFCT_DT<= GIV23_REJ_DT,
If(GAC12_EXPIRE_DT>GIV23_REJ_DT,
If(GAC15_EFCT_DT<= GIV23_REJ_DT,
If(GAC15_EXPIRE_DT>GIV23_REJ_DT,
(GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,
Null())))))
項目 GAC12_STD_COST と GAC15_EXCHANGE_RATE を SCD (穏やかに変化する軸) として読み取ります
拡張された intervalmatch 構文を使用した穏やかに変化する軸 (SCD) 問題の解決
テキストのソート
QlikView は、項目を数値、テキスト、汎用のどれとして処理するか自動的に評価します。テキストとして評価された項目は、ソート操作に最も時間がかかるテキストとしてソートされます。これを load order でソートするように手動で置き換えることができます。リスト ボックスなどでソートが必要でない場合は、無効にします。
QlikView は、文字と数値が混在する文字列を、アルファベット順にソートします。つまり、従来のASCIIコードのみのソート順とは異なり、数字は数値順にソートされ、非数字はASCIIコード順にソートされます。例:
ASCII ソート | アルファベット ソート |
---|---|
A1 | A1 |
A10 | A4 |
A11 | A5 |
A30 | A6 |
A4 | A10 |
A5 | A11 |
A6 | A30 |
動的なキャプションおよびテキスト オブジェクト
テキストを入力できるほぼすべての場所に、動的計算式を入力できます。ただし、数式の評価に必要なリソースは、環境によって異なります。数式ダイアログで定義されるチャートおよびテーブル内の数式は、オブジェクトが表示されるときとデータが変更されるときにのみ計算されます。したがって、オブジェクトが最小化されている場合は計算されません。
一方、オブジェクトのタイトルが計算される場合は、何らかの変更が発生するたびに計算が実行されます。表示条件、計算条件などを定義する方法も多くあります。このようなテストも毎回実行されます。
ある数式は他の数式より負荷が大きく、評価回数が多くなるとさらに負荷が大きくなります。非同期の計算の導入によってこの動作は変化しており、それらの効果もアプリケーション内でわかりやすくなっています。
Now()、Today() などの時間関数は、再計算が必要な場合に必ず評価されます。特に、Now() 関数は、毎秒アプリケーションで再計算されるため、負荷が大きくなります。
例:
If ( ReloadTime()+3>Now(), 'Old Data', 'New Data')
次の例もあります。
If ( ReloadTime()+3>Today(), 'Old Data', 'New Data')
簡単なテストとして、これらの数式をテキスト ボックスに置きます。Now() が中にあるテキスト ボックスをサイズ変更してみてください。
マクロのトリガー ("変更時")
マクロは、アプリケーション内で発生するほとんどのイベントでトリガーするように設定できます。あるイベントが次のイベントをトリガーし、それがさらに次のイベントをトリガーするようなイベントのカスケードまたは再帰的なイベントに注意してください。