上午在烏干達喬希。我創建了一個mnesia分片表(64個片段),並設法將它填充到9948723條記錄。每個片段是一個disc_copies類型,有兩個副本。 現在,使用qlc(查詢列表理解)在搜索記錄時速度太慢,並且返回不準確的結果。使用QLC查詢mnesia碎片表返回錯誤結果
我發現這個開銷是qlc使用mnesia的select函數遍歷整個表以匹配記錄。我嘗試了下面的其他東西。
-define(ACCESS_MOD,mnesia_frag).
-define(DEFAULT_CONTEXT,transaction).
-define(NULL,'_').
-record(address,{tel,zip_code,email}).
-record(person,{name,sex,age,address = #address{}}).
match()-> Z = fun(Spec) -> mnesia:match_object(Spec) end,Z.
match_object(Pattern)->
Match = match(),
mnesia:activity(?DEFAULT_CONTEXT,Match,[Pattern],?ACCESS_MOD).
嘗試此功能給了我很好的結果。但是我發現我必須爲存儲過程中的每個搜索動態構建模式。
我決定要經歷這樣的破壞,所以我寫了一些函數,這些函數會根據要搜索的參數爲我的記錄動態創建百搭圖案。
%% This below gives me the default pattern for all searches ::= {person,'_','_','_'}
pattern(Record_name)->
N = length(my_record_info(Record_name)) + 1,
erlang:setelement(1,erlang:make_tuple(N,?NULL),Record_name).
%% this finds the position of the provided value and places it in that
%% position while keeping '_' in the other positions.
%% The caller function can use this function recursively until
%% it has built the full search pattern of interest
pattern({Field,Value},Pattern_sofar)->
N = position(Field,my_record_info(element(1,Pattern_sofar))),
case N of
-1 -> Pattern_sofar;
Int when Int >= 1 -> erlang:setelement(N + 1,Pattern_sofar,Value);
_ -> Pattern_sofar
end.
my_record_info(Record_name)->
case Record_name of
staff_dynamic -> record_info(fields,staff_dynamic);
person -> record_info(fields,person);
_ -> []
end.
%% These below,help locate the position of an element in a list
%% returned by "-record_info(fields,person)"
position(_,[]) -> -1;
position(Value,List)->
find(lists:member(Value,List),Value,List,1).
find(false,_,_,_) -> -1;
find(true,V,[V|_],N)-> N;
find(true,V,[_|X],N)->
find(V,X,N + 1).
find(V,[V|_],N)-> N;
find(V,[_|X],N) -> find(V,X,N + 1).
雖然計算密集型,但工作得很好。 甚至在更改記錄定義後它仍然可以工作,因爲在編譯時它會得到新的記錄信息
問題是,當我在運行WinXP的3.0 GHz奔騰4處理器上啓動甚至25個進程時,很長時間才能返回結果。
如果我要在這些片段中使用qlc,爲了獲得準確的結果,我必須指定要搜索的片段。
find_person_by_tel(Tel)->
select(qlc:q([ X || X <- mnesia:table(Frag), (X#person.address)#address.tel == Tel])).
select(Q)->
case ?transact(fun() -> qlc:e(Q) end) of
{atomic,Val} -> Val;
{aborted,_} = Error -> report_mnesia_event(Error)
end.
Qlc正在返回[],當我搜索的東西,但當我使用match_object/1我得到準確的結果。我發現使用match_expressions可以提供幫助。
mnesia:table(Tab,Props)。 其中Props是一個數據結構,它定義了匹配表達式,返回值的塊大小e.t.c
當我試圖動態地構建匹配表達式時遇到了問題。
函數mnesia:讀/ 1或函數mnesia:讀/ 2,您需要有主鍵
現在問自己,我怎麼能有效地使用QLC在一個大的零散表搜索記錄?請幫忙。
我知道使用記錄的元組表示法會使代碼難以升級。這就是爲什麼 我討厭使用mnesia:select/1,mnesia:match_object/1,我想堅持QLC。 QLC在我的查詢中給出了錯誤的結果,即使在同一個節點上也有64個片斷的mnesia表。
有沒有人使用過QLC查詢分段表?請幫