erlang - как сопоставить содержимое кортежа с qlc и mnesia? - PullRequest
4 голосов
/ 22 июля 2009

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

-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])

Спасибо.

Ответы [ 2 ]

3 голосов
/ 23 июля 2009

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

0 голосов
/ 22 июля 2009

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

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

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

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

...