从Mnesia获取大量数据 - 最快的方式

时间:2011-12-19 23:34:57

标签: erlang mnesia

我有一个记录:

-record(bigdata, {mykey,some1,some2}).

正在做

mnesia:match_object({bigdata, mykey, some1,'_'})

获取超过5000行的最快方式?

澄清: 创建“自定义”键是一个选项(所以我可以读取)但是在一个键上比match_object执行5000次读取最快?

3 个答案:

答案 0 :(得分:2)

我很好奇你要解决的问题,表中有多少行等等,如果没有这些信息,这可能不是一个相关的答案,但是...

如果你有一个包,那么最好在密钥上使用read / 2然后遍历返回的记录列表。如果可能的话,最好构建数据以避免选择和匹配。

通常,select / 2比match_object更受欢迎,因为它往往更好地避免全表扫描。此外,假设您不需要事务支持,dirty_select将比select / 2更快。而且,如果你能忍受这些约束,Mensa允许你直接反对底层的ets表,速度非常快,但是只要在非常稀疏的情况下才能查看文档。

答案 1 :(得分:1)

Mnesia更像是一个键值存储系统,它将遍历所有记录以获得匹配。

要快速获取,您应该设计存储结构以直接支持查询。将some1作为键或索引。然后按readindex_read

获取它们

答案 2 :(得分:0)

Fastest Wayreturn more than 5000 rows的陈述取决于相关问题。什么是数据库结构?我们想要什么 ?什么是记录结构?之后,它归结为您编写读取函数的方式。如果我们确定主键,那么我们会使用mnesia:read/1 or mnesia:read/2,如果没有,则使用Query List comprehensions会更好,更漂亮。它更灵活地搜索嵌套记录和复杂的条件查询。见下面的用法:

-include_lib("stdlib/include/qlc.hrl").
-record(bigdata, {mykey,some1,some2}).


%% query list comprehenshions
select(Q)->
    %% to prevent against nested transactions
    %% to ensure it also works whether table
    %% is fragmented or not, we will use
    %% mnesia:activity/4

    case mnesia:is_transaction() of
        false -> 
            F = fun(QH)-> qlc:e(QH) end,
            mnesia:activity(transaction,F,[Q],mnesia_frag);
        true -> qlc:e(Q)
    end.

%% to read by a given field or even several
%% you use a list comprehension and pass the guards
%% to filter those records accordingly

read_by_field(some2,Value)->
    QueryHandle = qlc:q([X || X <- mnesia:table(bigdata),
                        X#bigdata.some2 == Value]),
    select(QueryHandle).

%% selecting by several conditions

read_by_several()->
    %% you can pass as many guard expressions

    QueryHandle = qlc:q([X || X <- mnesia:table(bigdata),
                            X#bigdata.some2 =< 300,
                            X#bigdata.some1 > 50
                            ]),
    select(QueryHandle).

%% Its possible to pass a 'fun' which will do the 
%% record selection in the query list comprehension

auto_reader(ValidatorFun)->
    QueryHandle = qlc:q([X || X <- mnesia:table(bigdata),
                        ValidatorFun(X) ==  true]),
    select(QueryHandle).

read_using_auto()->
    F = fun({bigdata,SomeKey,_,Some2}) -> true;
            (_) -> false
        end,
    auto_reader(F).

所以我认为如果你想要最快的方式,我们需要更多的澄清和问题细节。速度取决于我亲爱的很多因素!