Mnesia:read,match_object,select和qlc查询的时间和空间效率

时间:2013-09-25 16:12:14

标签: erlang mnesia

Mnesia有四种从数据库中读取的方法:readmatch_objectselectqlc。当然,除了他们的脏对手。他们每个人都比以前更具表现力。

  1. 其中哪一个使用指数?
  2. 鉴于其中一种方法中的查询,更具表现力的方法中的相同查询在时间/内存使用方面效率会降低吗?多少钱?
  3. UPD。 正如提到的I GIVE CRAP ANSWERSread只是一个键值查找,但经过一段时间的探索后,我发现函数index_readindex_write,它们以相同的方式工作但使用索引而不是主键。

1 个答案:

答案 0 :(得分:4)

一次一个,虽然来自记忆:

  • read始终在keypos上使用密钥查找。它基本上是键值查找。
  • match_objectselect会优化查询,如果它可以在keypos密钥上。也就是说,它只使用该密钥进行优化。它从不使用其他索引类型。
  • qlc有一个查询编译器,如果可能的话会尝试使用其他索引,但这一切都取决于查询规划器以及它是否触发。 erl -man qlc有详细信息,您可以要求它输出计划。

Mnesia表基本上是从术语到术语的键值映射。通常,这意味着如果 key 部分是查询可以锁定并使用的东西,则使用它。否则,您将看到全表扫描。这可能很昂贵,但要注意扫描是在内存中,因此通常相当快。

另外,请注意表类型:set是一个哈希表,不能使用部分密钥匹配。 ordered_set是一棵树,可以进行部分匹配:

示例 - 如果我们有一个密钥{Id, Timestamp},则在{Id, '_'}上查询ordered_set,因为字典排序意味着我们可以在{{1}}上快速 利用这棵树快速散步。这相当于在传统的RDBMS中指定复合INDEX / PRIMARY KEY。

如果您可以安排数据,以便您可以在没有其他索引的情况下进行简单查询,那么首选该表示。另请注意,其他索引实现为包,因此如果索引有许多匹配项,则效率非常低。换句话说,您可能不应该索引元组中几乎没有不同值的位置。最好对具有许多不同(大多数)不同值的事物建立索引,例如用户列的电子邮件地址。