Получение большого количества данных из Mnesia - самый быстрый способ - PullRequest
1 голос
/ 20 декабря 2011

У меня есть запись:

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

Делает ли

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

самый быстрый способ получения более 5000 строк?

Пояснение: создание "пользовательского"keys - это опция (поэтому я могу читать), но делает ли 5000 операций чтения быстрее, чем match_object на одном ключе?

Ответы [ 3 ]

2 голосов
/ 20 декабря 2011

Мне любопытно, какую проблему вы решаете, сколько строк в таблице и т. Д., Без этой информации это может быть неуместным ответом, но ...

Если у вас естьсумку, тогда может быть лучше использовать read / 2 на ключе, а затем просмотреть список возвращаемых записей.Было бы лучше, если это возможно, структурировать ваши данные, чтобы избежать выбора и совпадения.

В общем случае select / 2 предпочтительнее, чем match_object, так как он лучше избегает полного сканирования таблицы.Кроме того, dirty_select будет быстрее, чем select / 2, при условии, что вам не нужна поддержка транзакций.И, если вы можете справиться с ограничениями, Mensa позволяет вам напрямую перейти к базовой таблице ets, что очень быстро, но посмотрите на документацию, так как она подходит только в очень ограниченных ситуациях.

1 голос
/ 20 декабря 2011

Mnesia - это скорее система хранения ключей и значений, и она будет проходить все свои записи для получения соответствия.

Для быстрого извлечения вы должны спроектировать структуру хранения так, чтобы непосредственно поддерживать запрос. Сделать some1 ключом или индексом. Затем найдите их по read или index_read.

0 голосов
/ 20 декабря 2011

Утверждение Fastest Way до return more than 5000 rows зависит от рассматриваемой проблемы. Какова структура базы данных? Что мы хотим ? какова структура записи? После этого все сводится к тому, как вы пишете свои функции чтения. Если мы уверены в первичном ключе, то мы используем mnesia:read/1 or mnesia:read/2, если нет, лучше и красивее использовать Понимание списка запросов . Его более гибкий поиск вложенных записей и сложных условных запросов. см использование ниже:

-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).

Так что я думаю, что если вы хотите самый быстрый способ, нам нужно больше разъяснений и деталей проблемы. Скорость зависит от многих факторов, мой дорогой!

...