关于erlang:Mnesia:读取,match_object,select和qlc查询的时间和空间效率

Mnesia: time and space efficiency of read, match_object, select, and qlc queries

Mnesia有四种从数据库中读取的方法:readmatch_objectselectqlc。当然还有肮脏的同行。它们每个都比以前的更具表达力。

  • 他们中的哪个使用索引?
  • 给定这种方法之一的查询,在更具表现力的方法中,相同的查询是否会因时间/内存使用效率而降低?多少?
  • UPD。
    正如我给出的答案,read只是一个键值查找,但是经过一段时间的探索,我发现还有函数index_readindex_write,它们的工作方式相同,但使用索引而不是主键。


    一次一次,尽管来自内存:

    • read始终在keypos上使用键查找。基本上是键值查找。
    • 如果match_objectselect可以按keypos键,则将优化查询。也就是说,它仅使用该密钥进行优化。它从不利用其他索引类型。
    • qlc有一个查询编译器,并在可能的情况下尝试使用其他索引,但是这完全取决于查询计划程序以及是否触发。 erl -man qlc具有详细信息,您可以要求其输出其计划。

    Mnesia表基本上是各个术语之间的键-值映射。通常,这意味着如果关键部分是查询可以锁定并使用的部分,则将其使用。否则,您将要进行全表扫描。这可能很昂贵,但请注意,扫描是在内存中进行的,因此通常相当快。

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

    示例-如果我们有键{Id, Timestamp},则在{Id, '_'}上查询{Id, '_'}作为键是相当快的,因为按字典顺序排序意味着我们可以利用树进行快速遍历。这等效于在传统RDBMS中指定复合INDEX / PRIMARY KEY。

    如果您可以安排数据以便无需附加索引即可进行简单查询,则首选该表示形式。还要注意,其他索引是作为包实现的,因此,如果一个索引有很多匹配项,那么它的效率将非常低。换句话说,您可能不应该在元组中几乎没有不同值的位置上建立索引。最好对具有许多不同(主要是)不同值的内容建立索引,例如,一个用户列的电子邮件地址。