mnesia数据库index的选择

之前刚说了mnesia的一些经验,不想回头就犯错了。这里给自己提醒下。

对于下列的数据结构:

       -record(worker, {id,
                       name,
                       desc,
                       state}).
       

其中,id是唯一的,name可能会重复,但几率较小,state只有4种,
wait/doing/done/error,表示状态。

我在创建的时候,name作为第二个索引,id自然的成了第一索引,一切
都没有问题。最后数据量大约超过了N百万条。

然后,其他的逻辑流程出现了问题,state变为doing状态,没有正确切
换到其他的状态,这样,这个worker就一直处于doing状态,为了重置这些
状态,需要遍历所有的doing状态的worker,并且根据一个过滤列表,检查
后重置为其他的状态,比如done还是wait

我一次检查几百到几万条不等,为了加快速度,就手动的给worker的数
据库再添加一个索引:state,然后悲剧就发生了。

数据库变的非常非常的占用内存,超过几十GB了,虽然我虚拟内存有上
百GB,但也不能这么用啊,关键是,其他的进程对这一数据库的操作就会
变的非常的慢,而且,由于系统内存耗光,整个系统也非常慢。

其实,原因也很简单,问题就在于索引的选择上。对于mnesia而言,为
了加快读取,会对数据库遍历,根据索引生成对应的列表,这样,当每操
作一条数据的时候,就会更新索引,对于上述例子而言,根据state生成的
每个状态的列表元素的个数都是恐怖的,达到了上百万量,这样,当操作
数据的时候,每次都要遍历这些上百万个元素,效率就会非常的低,换言
之,state不适合做索引,而适合做分表

在索引选择上,每个属性对应的数据个数越少,越适合做索引,反之,
适合做分表。

发布者

rix

如果连自己都不爱自己,哪还有谁来爱你