ログ日記

作業ログと日記とメモ

GAE/J で 一対多の get、query の速度

直感的にはModelにKeyのリストを保持しておいて、Datastore.get(Child.class, keys)をやった方が速いと思っていたがInverseModelListRefを使ったqueryの方が速かった。


と言っても大した量でテストしてないんだけど、一応メモを残しておく。
ツリー構造のディレクトリのようなエンティティを200ほど登録していて、そのうち5件だけ持ってくる。
親に子のModelのキーのリストを保持しておいてDatastore.getで取得する場合と、親のInverseModelListRefを使った場合。

        String ret = "";
        long start = System.currentTimeMillis();
        Node parent = Datastore.get(Node.class, rootNode.getKey());
        List<Node> list = Datastore.get(Node.class, parent.getChildKeys());
        long end = System.currentTimeMillis();
        ret = "Datastore.get " + (end - start) + "ms";

        parent = Datastore.get(Node.class, rootNode.getKey());
        start = System.currentTimeMillis();
        list = parent.getChildrenRef().getModelList();
        end = System.currentTimeMillis();
        ret += "\n InverseModelListRef  " + (end - start) + "ms";

appengineにデプロイ直後は

Datastore.get 17ms
InverseModelListRef 118ms

だけど、二回目からは

Datastore.get 15ms
InverseModelListRef 8ms

となった。


念のため逆順でやってみると

InverseModelListRef 74ms
Datastore.get 17ms

InverseModelListRef 9ms
Datastore.get 16ms

となった。


なんだかよく分からない。KeyのリストでDatastore.getする場合は大体一定時間だ。InverseModelListRefは、デプロイ直後だけ遅くて、二回目からはこっちの方が速い。
エンティティを全部消してから実行するとInverseModelListRefが遅くなったりならなかったり。ムラが激しい。


Bigtable内でデータの分散配置待ちなのか?と思ってデプロイ後にしばらく待ってから実行したら速くなった。つまりエンティティを一気に更新した直後はDatastore.get(keys)の速度は一定だけどInverseModelListRef.getModelList()は遅くなる、大量に更新した直後でなければInverseModelListRef.getModelList()の方が速い、ということでいいんだろうか。




テスト用のコードを書いたわけでもなく今書いてるアプリにちょっとしたコードを追加して測っただけなので…というか上限があるから大量のデータを突っ込んで真面目にテストするには気が引ける。


暫定の結論としては、InverseModelListRefよりList<Key>の方が速い気がしたが気のせいだった。ということで。
Keyのリストを持つのはやめて全部InverseModelListRefにしようか。
そうすると並べ替え用のプロパティが必要か…。もう少し考える。