Mongodb中DBRef对比测试

Mongodb中DBRef对比测试

预计测试数据量100w,从测试结果来看很明显的区别就是插入性能。

(注意:本次测试并非很全面,没有考虑各种环境对测试结果的影响)

【测试环境】

操作系统:win10 

  数据库:Mongodb3.0

使用框架:Spring-Data-Mongo、Junit...

测试代码

Domain 伪代码。(注意@Data是lomback注解)

@Data
@Document(collection = "my_project2")
public class ProjectEntity2 {
    //project id
    private String id;
    //project name
    @Indexed
    private String name;

//  @DBRef(db="my_items")
    private List<Item> items;
}


@Data
@Document(collection = "my_item2")
public class Item {
    private String id;
    @Indexed
    private String name;

    private String description;
}


单元测试代码

// 插入测试
    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void testSave() throws Exception {
        long a = System.currentTimeMillis();

        for(int i = 1;i<= 1000000; i++){
            ProjectEntity2 projectEntity = new ProjectEntity2();
            projectEntity.setName("大医院" + i);

            Item item = new Item();
            item.setName("haha");
            item.setDescription("miaoshu  xinxi ");
//            mongoTemplate.save(item);
            Item item2 = new Item();
            item2.setName("haha1");
            item2.setDescription("miaoshu  xinxi2 ");
//            mongoTemplate.save(item2);
            List<Item> items = Arrays.asList(item,item2);
            projectEntity.setItems(items);
            mongoTemplate.save(projectEntity);
            System.out.println(i);

        }

        long b = System.currentTimeMillis();

        System.out.println(b-a);
    }
// 查询测试

    @Autowired
    private MongoTemplate mongo;


    /**
     * 查询D 
     */
    @Test
    public void testFindById() throws Exception {
        long a = System.currentTimeMillis();
        ProjectEntity2 aa = mongo.findById("58104368e961b02c30c46200",ProjectEntity2.class);
        long b = System.currentTimeMillis();
        System.out.println(b -a);
        System.out.println(JSON.toJSONString(aa));
    }

    /**
     * 查询列表 
     */
    @Test
    public void testFindList() throws Exception {
        long a = System.currentTimeMillis();
        Query query = new Query();
        query.limit(100).skip(3440);
        List<ProjectEntity2> aa = mongo.find(query,ProjectEntity2.class);
        long b = System.currentTimeMillis();
        System.out.println(b -a);
        System.out.println(JSON.toJSONString(aa));
    }


测试过程

======= == DBRef 性能测试========== 
【project数据结构】
{
    _id
    - name
    - items:[// DBRef
        {
            $id
            $ref
       }
    ]
}
100w 条数据插入 耗时 295754毫秒 = 4.9 分钟

   单条数据查询(4次): 188ms | 923ms | 136ms | 167ms
批量查询100条(4次):668ms | 546ms | 645ms | 1040ms
======= == 冗余性能测试==========
【project数据结构】
{
    _id
    - name
    - items:[
        {
            _id
            name
       }
    ]
}

100w 条数据插入 耗时127354 毫秒 = 2.1 分钟
   单条数据查询(4次):175 ms | 148ms | 145ms | 193ms
批量查询100条(4次):721ms | 722ms |  425ms | 301ms

总结

mongodb提供的 $ref 引用另外表数据的功能,影响插入性能明显!原因是在做插入操作的时候对数据进行了多次写入。

因此在决定使用DBRef功能前,需要综合分析实际应用场景。可能会有单个document超过了30MB限制了考虑使用DBRef,但我认为在单条数据超过了30MB的数据库设计问题。

DBRef处理数据冗余还是很有优势,使用或者不使用毕竟查询性能都差不多。使用了减少冗余存储,而存储过的DBRef引用数据只需要知道_id而不需要再次存储,也就解决了插入性能问题。

来源: 雨林博客(www.yl-blog.com)