4

问题:

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

例子

我有记录,

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

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

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

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 函数甚至使用底层索引吗?
  • 在这种情况下是否有更好的方法来利用索引
  • 我应该采取完全不同的方法吗?

谢谢你们

4

1 回答 1

4

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

但主要问题是 mnesia 中的索引是散列,因此不支持范围查询。因此,您只能在type当前字段上有效地索引而不是在last_update字段上。

解决此问题的一种方法是制作表格ordered_set,然后将其推last_update为主键。key如果您需要快速访问该参数,则可以对其进行索引。一种存储可能性类似于:{{last_update, key}, key, type, ...}. 因此,您可以快速回答查询,因为last_update它是可订购的。

另一种解决方法是单独存储上次更新。保留一个{last_update, key}有序集的表,并使用它来限制在查询中对较大表进行扫描的数量。

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

于 2012-10-17T15:04:30.590 回答