QlikViewのApplyMapとJoinはどっちが速い?


数千万件のデータロードを行う場合、ApplyMapを使用すると処理に時間がかかるため、Joinに切り替えて大幅に短縮したことがある。
ではどれくらい違うのか実験してみた。

Mapping Load ~ ApplyMapのスクリプト

Mapping Loadは変換テーブルの作成、ApplyMapでMapping tableを呼び出し変換する。
想像すればわかるが、ロードする時に1行単位で変換するから遅い。
スクリプトは以下のとおり。

Mapping_Load
LET vRap = Now();

Map_Customer:
Mapping
LOAD *
FROM
Customer.qvd(qvd);

LET vRap1 = interval(Now() - '$(vRap)');

Transaction:
LOAD *,
     ApplyMap('Map_Customer',customer_id)    as customer_name
FROM
Transaction.qvd(qvd);

LET vRap2 = interval(Now() - '$(vRap)');

Left Join Load ~ のスクリプト

Left JoinはSQLのJoin同様だから説明は割愛。
1行単位で変換するということではないが、やはり大量データのJoinは時間がかかる。
スクリプトは以下のとおり。

Join
LET vRap = Now();

Transaction:
LOAD * FROM
Transaction.qvd(qvd);

LET vRap1 = interval(Now() - '$(vRap)');

Left Join(Transaction)
LOAD *
FROM
Customer.qvd(qvd);

LET vRap2 = interval(Now() - '$(vRap)');

結果比較

今回のスクリプトは100,000,000件のTransactionに対して、Customer 1,000,000の変換(あるいはJoin)の処理である。
元データはここで作成したものだ。

  • ApplyMap
    • Mapping Load -> 2sec
    • TransactionのLoad(ApplyMap) -> 159sec
  • Left Join
    • TransactionのLoad -> 60sec
    • Join -> 44sec

結果を見れば、Joinのほうが速いね(1.5倍強)。特にデータ件数が多くなるとそれだけ差が出る。
よくLoad文の中で複数のApplyMapを使用しているケースがあるが、これは相当遅くなることになるんだろう。
しかしながら、ApplyMapでは変換できない場合の値を指定できるのは便利。Joinで行った場合は、nullの場合を埋める処理のためにもう一度Loadしなければならない。
その場合、ApplyMapのない場合のLoadは60secだから、ApplyMapを使用すた場合と全体の処理時間はほぼ同じということになる。

どちらがいいとは一概には言えないが、上記の結果を踏まえて、トランザクションテーブルとマスタとの整合性がある場合はJoinが良さそう..ということになるかな。