私は約90kの文書を持つデータベース(couchDB)を持っています。ドキュメントは次のように非常にシンプルです:非常にゆっくりとしたフィルターcoulderであっても
{
"_id": "1894496e-1c9e-4b40-9ba6-65ffeaca2ccf",
"_rev": "1-2d978d19-3651-4af9-a8d5-b70759655e6a",
"productName": "Cola"
}
私はこのデータベースをモバイルデバイスと同期させたいと思います。明らかに90kのドキュメントは一度にすべて電話に送られるべきではありません。これがフィルター関数を書いた理由です。これらは "productName"でフィルタリングされています。 Javascriptで最初はErlangでパフォーマンスを得る。これらのフィルタ機能は、JavaScriptで次のようになります。
{
"_id": "_design/local_filters",
"_rev": "11-57abe842a82c9835d63597be2b05117d",
"filters": {
"by_fanta": "function(doc, req){ if(doc.productName == 'Fanta'){ return doc;}}",
"by_wasser": "function(doc, req){if(doc.productName == 'Wasser'){ return doc;}}",
"by_sprite": "function(doc, req){if(doc.productName == 'Sprite'){ return doc;}}"
}
}
とErlangの中にこのような
:{
"_id": "_design/erlang_filter",
"_rev": "74-f537ec4b6508cee1995baacfddffa6d4",
"language": "erlang",
"filters": {
"by_fanta": "fun({Doc}, {Req}) -> case proplists:get_value(<<\"productName\">>, Doc) of <<\"Fanta\">> -> true; _ -> false end end.",
"by_wasser": "fun({Doc}, {Req}) -> case proplists:get_value(<<\"productName\">>, Doc) of <<\"Wasser\">> -> true; _ -> false end end.",
"by_sprite": "fun({Doc}, {Req}) -> case proplists:get_value(<<\"productName\">>, Doc) of <<\"Sprite\">> -> true; _ -> false end end."
}
}
まだクエリが、「ハードコードされた」という文字列がありませんそれをシンプルに保つために。フィルタはすべて動作します。問題は、彼らが遅くする方法だということです。私はPerlで最初にJavaでテストプログラムを書いて、ドキュメントをフィルタリングするのにかかる時間をテストしました。ここで私のPerlスクリプトの1つ:
$dt = DBIx::Class::TimeStamp->get_timestamp();
$content = get("http://127.0.0.1:5984/mobile_product_test/_changes?filter=local_filters/by_sprite");
$dy = DBIx::Class::TimeStamp->get_timestamp() - $dt;
$dm = $dy->minutes();
$dz = $dy->seconds();
@contArr = split("\n", $content);
$arraysz = @contArr;
$arraysz = $arraysz - 3;
$\="\n";
print($dm.':'.$dz.' with '.$arraysz.' Elements (JavaScript)');
そして今は悲しい部分です。これらは私が得る時である:
2:35 with 2 Elements (Erlang)
2:40 with 10000 Elements (Erlang)
2:38 with 30000 Elements (Erlang)
2:31 with 2 Elements (JavaScript)
2:40 with 10000 Elements (JavaScript)
2:51 with 30000 Elements (JavaScript)
btwこれらは分:秒です。数値はフィルタによって返される要素の数であり、データベースには90kの要素があります。大きな驚きはErlangフィルタがまったく高速ではなかったことです。
すべての要素を要求するには、9秒かかります。そして、約15のビューを作成します。しかし、私は電話ですべてのドキュメント(ボリュームとセキュリティの理由)を転送することはできません。
パフォーマンスを向上させるためにビューをフィルタリングする方法はありますか? 私のerlangフィルタ関数に何か問題があります(私はJavaScriptフィルタの時代に驚いていません)。
EDIT: pgrasが指摘しているように、これが遅い理由はthis質問の回答に掲載されています。 erlangフィルターをより速く動かすには、以下の「レイヤー」に行き、erlangを_design文書ではなくデータベースに直接プログラムする必要があります。しかし、私はどこで始めるべきか、これをどうやって行うのか本当に知りません。あらゆるヒントが役立ちます。
_changesをsinceパラメータなしで使用すると、最初の同期後にDBのすべてのコンテンツがフィルタリングされます後続の同期にsinceパラメータを使用する予定ですか?あなたは、ビューを使用して言及すると、あなたの他のニーズを解決するキー= "ファンタ"とのファーストビューですか? – pgras
後でデータベースをモバイルデバイスに複製するためにフィルタを使用したいが、私はフィルタをテストするためだけにhttp要求を使用した。私はレプリケーションのためにフィルタを使ってみましたが、同様の結果が得られました。私は後でそこにフィルタを使ったクエリがあるはずだから、ビューが助けになるとは思わない。 –
同じことをやっています。 Erlangをフィルタリングされた複製に使用すると約55%の改善が得られましたが、それでもなお痛みを伴います。 – ryan1234