У меня есть база данных (couchDB) с около 90k документами в ней. Документы очень просты:
{
"_id": "1894496e-1c9e-4b40-9ba6-65ffeaca2ccf",
"_rev": "1-2d978d19-3651-4af9-a8d5-b70759655e6a",
"productName": "Cola"
}
теперь я хочу, чтобы в один день была синхронизирована эта база данных с мобильным устройством. Очевидно, 90k docs не должны сразу заходить в телефон. Вот почему я написал функции фильтра. Они должны фильтроваться с помощью "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."
}
}
Чтобы это было просто, пока еще нет запроса, а "жестко закодированная" строка. Фильтр работает. Проблема в том, что это способ замедлить работу. Сначала я написал тестовую программу на Java позже в 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 элементов. Большой сюрприз заключался в том, что фильтр Эрланг не был быстрее.
Для запроса всех элементов требуется всего 9 секунд. И создание просмотров около 15. Но мое использование на телефоне не может передать все документы (объем и причины безопасности).
Есть ли способ фильтровать представление, чтобы увеличить производительность? Или что-то не так с моими фильтрами erlang (я не удивляюсь временам для фильтров JavaScript).
EDIT: Как указано pgras, причина, по которой это происходит медленно, отправляется в ответ на этот Вопрос. Чтобы фильтры erlang выполнялись быстрее, мне нужно перейти на "слой" ниже и запрограммировать erlang непосредственно в базу данных, а не как документ _design. Но я не знаю, с чего начать и как это сделать. Любые советы будут полезны.