erlang - how can I match tuple contents with qlc and mnesia?

青春壹個敷衍的年華 提交于 2019-12-23 12:19:17

问题


I have a mnesia table for this record.

-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 is a tuple {FileId, ClientId}, now I need to extract the ip_port field from all peers that have a specific FileId.

I came up with a workable solution, but I'm not sure if this is a good approach:

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

Thanks.


回答1:


Using on ordered_set table type with a tuple primary key like { FileId, PeerId } and then partially binding a prefix of the tuple like { RequiredFileId, _ } will be very efficient as only the range of keys with that prefix will be examined, not a full table scan. You can use qlc:info/1 to examine the query plan and ensure that any selects that are occurring are binding the key prefix.




回答2:


Your query time will grow linearly with the table size, as it requires scanning through all rows. So benchmark it with realistic table data to see if it really is workable.

If you need to speed it up you should focus on being able to quickly find all peers that carry the file id. This could be done with a table of bag-type with [fileid, peerid] as attributes. Given a file-id you would get all peers ids. With that you could construct your peer table keys to look up.

Of course, you would also need to maintain that bag-type table inside every transaction that change the peer-table.

Another option would be to repeat fileid and add a mnesia index on that column. I am just not that into mnesia's own secondary indexes.



来源:https://stackoverflow.com/questions/1161831/erlang-how-can-i-match-tuple-contents-with-qlc-and-mnesia

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!