Qlik Sense Desktop × Surface Pro3で10億件のデータを試してみる

# 概要
[Tableau × R で時系列分析をやってみる](http://qiita.com/yatarou/items/7bb9381e6586b9318aa6)にインスパイアされました。
といっても、Rとの連携に関しては、既に[Qlik SenseでR/Shinyを使う（実験段階）](http://qiita.com/sasanquaneuf/items/cd4aefdd466c4c999d99)という記事でも触れているので、ここでは大量データをオンメモリーで本当に処理できるかどうか、を試してみます。
具体的には、**適度にカーディナリティの低いデータ**を用いて、Surface Pro3のスペックで10億件のレコードを処理するのにどれぐらい時間がかかるのか、ということを試します。

# 実験１

## 詳細について

上でも少し書いていますが、QlikView/Qlik Senseは、カーディナリティが低いデータが非常に得意です。カーディナリティが高いデータについては、特別に不得意ということは無いのですが、カーディナリティが低い場合の他のツールとの差が圧倒的だと思っています。（きちんと試した訳ではないのですが…）
そこで、今回は次のようなプログラムでダミーデータを生成し、まず1億件のデータの処理がどれぐらいでできるのか、を調べます。

```csharp:Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            StreamWriter sw = new StreamWriter(@"c:\a_test\dummy_data.txt");
            var r = new Random();
            sw.WriteLine("区分1,区分2,区分3,金額");
            for (long i = 0; i < 100000000; i++)
            {
                sw.WriteLine(r.Next(5) + "," + r.Next(5) + "," + r.Next(10) + "," + 500 * r.Next(20));
            }
            sw.Close();
        }
    }
}
```
見てわかる通り、区分1,区分2,区分3,金額という謎の4つの項目を持ち、区分1～3は5種類、金額は20種類の離散的な値を取ります。

## データロード
Qlik Senseを立ち上げ、アプリの新規作成を選び、GUIに従ってデータを追加します。
<img width="412" alt="test01.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/4345aac2-5698-721f-ceb6-e39530008ea6.png">
<img width="420" alt="test02.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/72eea1bf-aaf2-0ac8-5376-78c39040ec66.png">
<img width="393" alt="test03.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/50a4c30d-fcb7-b795-4a88-2ae6d8d87c3d.png">
<img width="853" alt="test04.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/d6e3676a-942a-a2aa-8ef1-cd8ea7a9b5f0.png">
<img width="852" alt="test05.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/039f4f08-1ca6-ab43-ab4a-4faddb29cefa.png">
約1GB、1億行の単純なカンマ区切りファイルですが、読み込みには1分41秒かかりました。
このデータの読み込みは、新しいデータをQlik Senseのファイルに取り込む際に必要なもので、一度取り込んだデータを処理する場合＝**保存されたファイルを単に開く場合には不要**です。
一般的には、バッチ処理等でサーバーで自動的にデータロードさせることが多いですが、Qlik Sense Desktopの場合、勝手にリロードする機能は無い為、都度必要に応じて自分でデータロードする必要があります。
ちなみに、この時のマシン負荷は図の通りです。(SurfacePro3/corei5/メモリ8GBモデル)
<img width="559" alt="test06.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/ef251833-4596-2f37-5af2-302b3339f587.png">

## アプリづくり
GUIに従って、ピボットテーブルを作ってみます。
<img width="852" alt="test07.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/03c21bcd-0265-3e5e-d6a8-cc8d2282c253.png">
<img width="858" alt="test08.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/927d4bc3-ef49-0583-abb4-84991a7c8042.png">
ピボットテーブルを表示したときの、マシン負荷も載せています。ほとんど負荷がかかっていませんが、計算はされています。計算にはほとんど時間がかかっていません。
この状態だと、区分2～区分3が閉じられているので、展開してみます。
<img width="722" alt="test09.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/8db37d8b-79e4-ec3b-c652-61ca6ce8efb7.png">
<img width="861" alt="test10.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/cac88b76-c407-2d81-1a2a-4f2d204282d8.png">
例によって、ほとんど負荷はかかりません。
ちなみに、このときQlik Sense Desktopのプロセスは約1.4GB程度メモリを消費していました。

## ファイルサイズ
Qlik Senseでは、データとUIコンポーネントをセットで「アプリ」として保存します。qvfというファイルになります。
<img width="337" alt="test11.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/d2ad52b8-c833-4c7b-0818-b951a1940958.png">
元々のサイズが約1GBなので、圧縮された状態になっています。
このあたりの詳細はここでは説明しませんが、超正規化とか連想技術とかで検索すると、何かが出てくると思います。

# 実験２
このカーディナリティの高さだと、Qlik Senseの限界を知ることは全くできませんでした。
データの量を10倍に増やして、10億件にしてみます。ついでに、カラムも一つ増やします。

## データロード
データをロードするスクリプトを編集して、ダミーデータをもっと増やします。
<img width="862" alt="test12.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/b8147758-68f1-b648-abc6-9535188f3bb3.png">
<img width="862" alt="test13.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/b29366e2-3cb2-dbf7-eaa2-2a270fe256fa.png">
元のスクリプトは単にデータを読み込んでいるだけですが、適当な計算処理や日付を付加する謎の処理を付け加えました。
データロード中の様子です。さすがに計算処理を付け加えると、かなり重くなるようです。
CPU負荷が逆に100%ではなくなってしまったのが面白いところでしょうか。
<img width="861" alt="test14.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/aba18f0c-1079-ffc3-556c-c2fe397327e9.png">
<img width="860" alt="test15.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/69773b9a-2607-a550-2d70-dc84cfa18a50.png">
<img width="859" alt="test16.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/d57a54db-69b5-bff6-d74f-1e25ae612a46.png">
一時間ちょっとかかりました。
データをロードした後、Qlik Senseの中で最適化する処理や、ファイルを保存する処理では負荷が上がっています。
また、メモリの使用量も増えました。増えましたと言っても、1GB弱ですが。

## アプリづくり
データロード後、アプリを開こうとすると、アプリを開くまでに20秒くらい？かかります。
途中でメモリが増えたり減ったりしますが、エラーは発生しませんでした。
<img width="518" alt="test17.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/86533659-2647-2c97-6c87-fa8b6ad38023.png">
QlikViewnだと、ここでメモリが増えすぎて開けない、ということがよくありました。

<img width="862" alt="test18.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/91a1a24a-f22c-f181-3f1a-643d7df3ddbb.png">
<img width="861" alt="test19.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/e7f3a94b-7d7b-539c-b4b8-de111266f25e.png">
<img width="862" alt="test21.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/a0a1c426-db64-8213-2a89-7f89d5e918ed.png">
<img width="861" alt="test20.png" src="https://qiita-image-store.s3.amazonaws.com/0/94255/dbcead2c-f9b7-9472-cf6f-addf5a3ba263.png">
ピボットの軸に日付をつけたりしています。操作毎に15秒ぐらいかかります。

ちなみに、メモリの使用量は2.4GBぐらいでした。

## ファイルサイズ
画像がありませんが、1.5GBになりました。日付をつけて10倍にしても、こんなもので済みます。

# まとめ
・Surface Pro3(corei5/8GB)レベルの端末であれば、10億件でも特にストレスなく処理できました。
・カーディナリティを高くした場合は、また別途機会があれば試します。