2011-12-19 62 views
1

我有一個紀錄:獲取大量的數據從Mnesia的 - 最快的方式

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

正在做

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

以最快的方式獲取超過5000行?

說明: 創建「自定義」鍵是一個選項(這樣我可以讀取),但是在單個鍵上做的速度比match_object快5000個?

回答

2

我很好奇,你要解決這個問題,有多少行的表等,沒有這些信息,這可能不是一個相關的答案,但...

如果你有一個那麼最好在密鑰上使用read/2,然後遍歷返回的記錄列表。如果可能的話,最好是結構化數據以避免選擇和匹配。

一般來說select/2比match_object更受歡迎,因爲它傾向於更好地避免全表掃描。另外,假設你不需要事務支持,dirty_select將會更快,然後選擇/ 2。而且,如果您可以忍受這些限制,Mensa允許您直接與底層ets表進行交易,但速度非常快,但請查看文檔,因爲它只適用於非常流行的情況。

1

Mnesia更多是一個關鍵值存儲系統,它將遍歷所有記錄以獲得匹配。

要快速獲取,您應該設計存儲結構以直接支持查詢。使some1成爲關鍵或索引。然後通過readindex_read取回。

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

所以我認爲如果你想要最快的方式,我們需要更多的澄清和問題的細節。速度取決於很多因素,我親愛的!

相關問題