Mnesia:如何在根据涉及多个索引列的条件选择行时正确使用索引操作

时间:2012-10-17 12:39:15

标签: erlang mnesia

问题:

如何从select表基于涉及两个索引列的条件的表中有效地选择记录。

实施例

我有记录,

#rec{key, value, type, last_update, other_stuff}
  • 我在key(默认),type和last_update列上有索引
  • type通常是一个原子或字符串
  • last_update是一个整数(自1970年以来的unix风格毫秒)

我想要,例如所有类型=类型且自特定时间戳以来已更新的记录。

我执行以下操作(包含在非脏事务中)

lookup_by_type(Type, Since) ->
    MatchHead = #rec{type=Type, last_update = '$1', _= '_'},
    Guard = {'>', '$1', Since},
    Result = '$_',
    case mnesia:select(rec,[{MatchHead, [Guard],[Result]}]) of
    []    -> {error, not_found};
    Rslts -> {ok, Rslts}
    end.

问题

  • lookup_by_type函数是否使用基础索引?
  • 在这种情况下是否有更好的方法来使用索引
  • 我应该采取完全不同的方法吗?

谢谢大家

1 个答案:

答案 0 :(得分:3)

可能对您有帮助的一种方法是查看QLC查询。这些是更多的SQL /声明,如果可能的话,它们将使用索引IIRC。

但主要问题是mnesia中的索引是哈希值,因此不支持范围查询。因此,您只能在type字段上有效地对last_update字段进行索引。

另一种方法是创建表ordered_set,然后将last_update推送为主键。如果您需要快速访问key参数,则可以将其编入索引。一种存储可能性类似于:{{last_update, key}, key, type, ...}。因此,您可以快速回答查询,因为last_update是可订购的。

另一种方法是分别存储最后更新。保留一个表{last_update, key},这是一个有序集,并使用它来限制在查询中较大的表上扫描的事物数量。

请记住,mnesia最适合用作小型内存数据库。因此,扫描不一定是问题,因为它们在内存中并且因此非常快。它的主要功能是能够以脏的方式对数据进行键/值查找以便快速查询。