我有一個數據庫(couchDB),其中包含約90k的文檔。這些文件都是這樣非常簡單:非常緩慢的couchDB過濾器甚至與erlang
{
"_id": "1894496e-1c9e-4b40-9ba6-65ffeaca2ccf",
"_rev": "1-2d978d19-3651-4af9-a8d5-b70759655e6a",
"productName": "Cola"
}
現在我想有一天這個數據庫與移動設備同步。很明顯,90k文檔不應該一次全部打到手機上。這就是我寫過濾器功能的原因。這些應該由「productName」過濾。最初在Javascript中使用Javascript來獲得性能。這些過濾器的功能看起來像這樣在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;}}"
}
}
像這樣在二郎:
{
"_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中首先編寫了一個測試程序,用於測試過濾文檔所需的時間。這裏是我的一個Perl腳本:
$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過濾器的時間並不感到驚訝)。
編輯: 正如pgras指出的,爲什麼這是緩慢的原因發佈在this問題的答案中。爲了讓erlang過濾器運行得更快,我需要下面的「圖層」,並將erlang直接編程到數據庫中,而不是_design文檔。但我真的不知道從哪裏開始以及如何做到這一點。任何提示將有所幫助。
你,因爲參數使用_changes沒有,所以它會過濾數據庫的所有內容,一旦第一同步你打算使用since參數進行後續同步嗎?你提到使用視圖,用快捷鍵「Fanta」快速查看解決你的其他需求? – pgras 2013-03-13 16:06:10
我想稍後使用過濾器將數據庫複製到移動設備,我只使用http請求來測試過濾器。我嘗試使用過濾器進行復制,並得到了類似的結果。我不認爲一個視圖會有幫助,因爲稍後會有一個過濾器查詢。 – 2013-03-13 16:32:49
經歷同樣的事情。使用Erlang進行過濾複製時,我獲得了大約55%的提升,但仍然非常緩慢。 – ryan1234 2013-03-14 23:01:08