erlang - как мне сопоставить содержимое кортежа с qlc и mnesia?

У меня есть таблица мнезии для этой записи.

-record(peer, {
    peer_key,   %% key is the tuple {FileId, PeerId}
    last_seen,
    last_event,
    uploaded = 0,
    downloaded = 0,
    left = 0,
    ip_port,
    key
}).

Peer_key - это кортеж {FileId, ClientId}, теперь мне нужно извлечь поле ip_port из всех пиров, у которых есть определенный FileId.

Я нашел работоспособное решение, но не уверен, что это хороший подход:

qlc:q([IpPort || #peer{peer_key={FileId,_}, ip_port=IpPort} <- mnesia:table(peer), FileId=:=RequiredFileId])

Спасибо.


person Matteo Caprari    schedule 21.07.2009    source источник


Ответы (2)


Использование типа таблицы order_set с первичным ключом кортежа, например {FileId, PeerId}, а затем частичная привязка префикса кортежа, например {RequiredFileId, _}, будет очень эффективным, поскольку будет проверяться только диапазон ключей с этим префиксом, а не полное сканирование таблицы. Вы можете использовать qlc: info / 1, чтобы изучить план запроса и убедиться, что все выполняемые выборки привязывают префикс ключа.

person user143785    schedule 23.07.2009

Время вашего запроса будет линейно расти с размером таблицы, так как для этого требуется сканирование всех строк. Так что сравните его с реалистичными табличными данными, чтобы увидеть, действительно ли он работает.

Если вам нужно ускорить это, вы должны сосредоточиться на возможности быстро найти всех одноранговых узлов, которые несут идентификатор файла. Это можно сделать с помощью таблицы типа bag с атрибутами [fileid, peerid]. Учитывая идентификатор файла, вы получите идентификаторы всех пиров. С его помощью вы можете создать ключи таблицы одноранговых узлов для поиска.

Конечно, вам также нужно будет поддерживать эту таблицу типа мешка внутри каждой транзакции, которая изменяет одноранговую таблицу.

Другой вариант - повторить fileid и добавить индекс мнезии в этот столбец. Я просто не в восторге от вторичных индексов Mnesia.

person Christian    schedule 22.07.2009