Я Джош в Уганде. Я создал фрагментированную таблицу мнений (64 фрагмента) и сумел заполнить ее до 9948723 записей. Каждый фрагмент был типа disk_copies с двумя репликами. Теперь при использовании qlc (понимание списка запросов) поиск записи выполнялся слишком медленно, и результаты возвращались неточные.
Я обнаружил, что эти накладные расходы заключаются в том, что qlc использует функцию выбора mnesia, которая проходит по всей таблице для сопоставления записей. я попробовал что-то еще ниже.
-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).
Это работало очень хорошо, хотя и требовало больших вычислительных ресурсов. Он все еще может работать даже после изменения определения записи, поскольку во время компиляции он получает новую информацию о записи.
Проблема в том, что когда я инициирую даже 25 процессов на процессоре Pentium 4 с тактовой частотой 3,0 ГГц под управлением WinXP, он зависает и требует много времени для возврата результатов.
Если я использую 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 может помочь.
мнения: таблица (вкладка, реквизит). где Props — это структура данных, которая определяет выражение соответствия, размер фрагмента возвращаемых значений и т. д.
У меня возникла проблема, когда я попытался динамически построить выражения соответствия.
Функция mnesia:read/1 или mnesia:read/2 требует наличия первичного ключа.
Теперь я спрашиваю себя, как я могу эффективно использовать QLC для поиска записей в большой фрагментированной таблице? Пожалуйста помоги.
Я знаю, что использование кортежного представления записей затрудняет обновление кода. Вот почему я ненавижу использовать mnesia:select/1, mnesia:match_object/1 и хочу придерживаться QLC. QLC дает мне неверные результаты в моих запросах из таблицы мнезии из 64 фрагментов даже на одном узле.
Кто-нибудь когда-либо использовал QLC для запроса фрагментированной таблицы? Помогите, пожалуйста.