论坛首页 综合技术论坛

mnesia索引字段的ets调用

浏览 3786 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-07   最后修改:2009-09-07
数据量庞大的时候,使用索引能极大的提高效率。但mnesia模块里只有index_read,index_match_object,match_object三个函数及其dirty版能够使用索引查询,在很多情况下这几个函数是不够用的,比如,当我们想判断某个索引值下是否存在记录,但用标准库提供的函数必须把记录全部复制出来,开销很大。

mnesia表的索引,底层上是使用一张ets表实现,索引ets表在mnesia启动的时候生成,表名是一个随机整数,每次启动都不一样,表类型是bag,表项是包含两个元素的元组,形如{Index,Id}。

通过这样的一张索引表,第一段里的问题,可以使用ets:member(EtsTable,Index)来解决。ets索引表的表名在mnesia表的信息里有,例如有表项为记录集record(object,{id,index,value})的mnesia表,索引为index,那么调用下面的函数便可以取得索引表名:
    EtsTable = table_index(object,#object.index).

这样,我们就可以使用ets模块里的大量函数提高程序的效率。

table_index函数定义如下:

table_index(Record,Seq)->
    RoleInfo = mnesia:table_info(Record,all),
    case lists:keyfind({index,Seq},1,RoleInfo) of
        false->
            ok;
        {_,Table}->
            Table
    end.
   发表时间:2009-09-08  
啊 有你这样用的吗? 把ets的记录变成列表来操作? 好好研究下match_spec 这些事情用spec来做不是小菜吗?
0 请登录后投票
   发表时间:2009-09-08   最后修改:2009-09-08
没有把ets变成列表,只是绕开了mnesia原表直接操作索引。mnesia模块里使用match_spec的函数只有dirty_select/2,select/2,select/3,select/4,都不能支持索引,效率很低的。

另外今天看mnesia的源码,发现它把索引表信息存在了一张系统的ets表里,可以直接用下面的方法获取,mnesia的各种索引操作也是通过它来实现的:

get_index_table(Record,Seq)->
    ets:lookup_element(mnesia_gvar, {Record,{index, Seq}}, 2).
0 请登录后投票
   发表时间:2009-09-09  
这个完全是hack方法 如果再fragment什么的 就完全出问题了 不是正统手段 不推荐。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics