2010-06-11 4 views
1

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 개의 조각으로 구성된 천궁 테이블에서 내 쿼리에 잘못된 결과를 제공합니다.

는 누구도?

답변

0

당신이 활동의 ​​맥락에서 QLC를 호출 마십시오 도와주세요 분할 된 테이블을 쿼리 QLC을 사용 했습니까?

tfn_match(Id) -> 
    Search = #person{address=#address{tel=Id, _ = '_'}, _ = '_'}, 
    trans(fun() -> mnesia:match_object(Search) end). 

tfn_qlc(Id) -> 
    Q = qlc:q([ X || X <- mnesia:table(person), (X#person.address)#address.tel == Id]), 
    trans(fun() -> qlc:e(Q) end). 

trans(Fun) -> 
    try Res = mnesia:activity(transaction, Fun, mnesia_frag), 
    {atomic, Res} 
    catch exit:Error -> 
    {aborted, Error} 
    end. 
관련 문제