2013-09-25 24 views
3

Mnesia的具有从数据库中读取四种方法:readmatch_objectselectqlc。当然除了他们肮脏的同行。他们每个人都比以前更有表现力。Mnesia的:时间和读取,match_object,选择的空间效率,并QLC查询

  1. 哪些人使用指数?
  2. 鉴于在这些方法之一中的查询,在更具表现力的方法中,相同的查询会因时间/内存使用而效率低下吗?多少?

UPD。 由于I GIVE CRAP ANSWERS提到,read只是一个键值查询,但经过一段时间的探索后,我发现功能index_readindex_write,其工作方式相同,但使用索引而不是主键。

回答

4

一次一个,虽然从内存:

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

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

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

例子 - 如果我们有一个关键{Id, Timestamp},在{Id, '_'}查询为重点相当快上ordered_set因为字典顺序意味着我们可以利用树的快走。这相当于在传统RDBMS中指定复合INDEX/PRIMARY KEY。

如果您可以安排数据,以便您可以在没有附加索引的情况下执行简单查询,那么该表示法是首选。还要注意,其他索引是作为行李来实现的,所以如果你有很多索引匹配,那么它效率很低。换句话说,你可能不应该索引在几乎没有明确值的元组中的位置。最好对许多不同(大多数)不同的值进行索引,例如用户列的电子邮件地址。

+0

我是对的,在'ordered_set'上用'{Id,Timestamp}'查询'{'_',Timestamp}'是一个慢操作吗? – citxx

+0

是的,你是。它必须扫描整个表格才能过滤出匹配的键。还要注意,一个典型的条目看起来像'{atom(),{Id,Timestamp},Value}'或类似的东西。 –

+1

这个答案只是一个小小的补充:如果mnesia表类型为set或ordered_set,Erlang的新版本使用duplicate_bag表来存储mnesia索引。这消除了很多与具有许多重复值的列索引相关的性能损失(我只是碰巧知道这一点,因为我自己编写了该补丁;-) – Nick