am josh가 잘못 반환됩니다. 나는 선천적 인 조각상의 테이블 (64 조각)을 만들었고 최대 9948723 개의 레코드까지 채워 넣었다. 각 조각은 두 개의 복제본이있는 disc_copies 유형입니다. 이제 qlc (쿼리 목록 이해)를 사용하여 레코드를 검색하는 데 너무 느리고 부정확 한 결과가 반환되었습니다.QLC를 사용하여 mnesia Fragmentated Tables를 쿼리하면 우간다에서
이 오버 헤드는 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 개의 조각으로 구성된 천궁 테이블에서 내 쿼리에 잘못된 결과를 제공합니다.
는 누구도?