【问题标题】:Match/Select from mnesia using prefix使用前缀从 mnesia 中匹配/选择
【发布时间】:2019-11-22 05:31:34
【问题描述】:

我有一个 mnesia 表,其中包含 id、name、city 等字段... 我想使用前缀选择/匹配名称,例如,如果有多个名称以“joe”开头的记录,我想在不迭代所有记录的情况下有效地选择所有记录。

就像 sql 查询 "select id from mytbl where name like joe%"。谢谢

更新:

基于 1000 条记录的基准测试:

MySql(名称也是主键):450-500 微秒

Mnesia 实际表(非键):300-370 微秒

以名称为键的单独的ordered_set mnesia 表:60-108 微秒

注意: mnesia 表只是 ram,即使在索引实际表的名称字段后,我也没有注意到任何性能差异。

【问题讨论】:

    标签: erlang mnesia


    【解决方案1】:

    类似:

    mnesia:select(mytbl, ets:fun2ms(fun(#mytbl{name = "joe" ++ _, id = Id}) -> Id end)).
    

    mnesia:select(mytbl, [{#mytbl{name = "joe" ++ '_', id = '$1', _ = '_'},[],['$1']}]).
    

    (这是match specification。这两个变体是等价的,但使用ets:fun2ms 生成匹配规范通常更清楚。您需要-include_lib("stdlib/include/ms_transform.hrl"). 才能被编译器接受。请注意,如果你在 shell 中尝试这个,只有后者会起作用,因为 an inconsistency 是由 ++ 处理的 ets:fun2ms。)

    请注意,这将在幕后仍然遍历所有记录,除非您的表是 ordered_set 类型并且 name 是主键。


    如果您想获取完整记录,而不仅仅是 id 字段,那就是:

    mnesia:select(mytbl, ets:fun2ms(fun(#mytbl{name = "joe" ++ _} = X) -> X end)).
    

    mnesia:select(mytbl, [{#mytbl{name = "joe" ++ '_', _ = '_'},[],['$_']}]).
    

    【讨论】:

    • 因为要频繁访问,是不是最好再创建一个ordered_set表,name为key,放一些atom或integer为value?
    • 另外,mnesia 表是从 mysql 中填充的,它与 mnesia 作为持久性数据库并行运行,如果我直接查询 mysql 而不是 mnesia 会有多大的性能差异?
    • 如果 mysql 可以为这样的前缀查询使用索引,我肯定会尝试一下,看看它的性能如何。否则一个单独的 ordered_set 表可能是要走的路。
    • 感谢您的时间和精力,我会做一些基准测试并分享结果。
    • 对于将来的参考,您可能必须将 Result 设置为 '$_' 而不是 '$1' 以获得完整记录,包括匹配的全名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 2019-01-09
    • 2011-09-05
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多