100萬數據插入 mongodb 性能測試

Mongodb服務器信息前端

8核16Gjava

 

開發臺式機信息web

固態硬盤、公司內部網絡redis

 

示例代碼spring

1.採用jdk1.8 + springboot2.1.6 + mongodb3.8.2組合而成的工程示例sql

2.mongodb4.0.11全部過程採用默認安裝,沒作特殊優化mongodb

3.測試表,只有主鍵,ID不自動生成數據庫

 

mongodb.sqlapi

db.getCollection('DbResult').insert({'_id':1,content:'test'});

pom.xml緩存

<!-- springboot框架包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 導入mongodb包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

application.properties

#tomcat address port
server.port=8089
server.address=127.0.0.1
server.sessionTimeout=30

spring.application.name=demo-web

#2.0 path
server.servlet.context-path=/api

#採用logback.xml配置日誌輸出模板 
logging.config=classpath:logback.xml

#springframework.web框架的日誌級別,注意與自已代碼中定義的日誌級別不同
logging.level.org.springframework.web:INFO
#是否啓用springboot的debug調試模式,會打印詳細日誌信息
debug=false

#mongodb datasource
spring.data.mongodb.host=192.168.110.01
spring.data.mongodb.port=27017
spring.data.mongodb.authentication-database=mydemo
spring.data.mongodb.database=mydemo
spring.data.mongodb.username=root
spring.data.mongodb.password=123456

Result.java

 

@Data
@Document(collection = "DbResult")
public class Result {
    @Id
    private long id;
    private String content;
}

ResultDao.java

@Repository("mongoResultDao")
public class ResultDao {
    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * 新增數據
     * @param result
     */
    public void insert(Result result){
        mongoTemplate.insert(result);
    }
    /**
     * 批量新增數據
     * @param resultList
     */
    public void insertResultBatch(List<Result> resultList){
        mongoTemplate.insert(resultList, Result.class);
    }
}

ResultService.java

@Service("mongoResultService")
public class ResultService {
    @Resource
    private ResultDao resultDao;
    /**
     * 新增數據
     * @param result
     */
    public void insert(Result result){
        resultDao.insert(result);
    }
    /**
     * 批量新增數據
     * @param resultList
     */
    public void insertResultBatch(List<Result> resultList){
        resultDao.insertResultBatch(resultList);
    }
}

ResultApi.java

@RestController("mongoResultApi")
@RequestMapping("/mongo/result")
public class ResultApi {
    @Resource
    private ResultService mongoResultService;
    /**
     * 批量添加新的對象
     * @return
     */
    @RequestMapping(value = "/batAdd", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Object batAdd(){
        Result result = null;
        String content = System.currentTimeMillis() + "";
        long startTime =  System.currentTimeMillis();
        for (int i=1001;i<=1001000;i++){
            result = new Result();
            result.setId(i);
            result.setContent(content);
            mongoResultService.insert(result);
        }
        ApiResult result1 = new ApiResult();
        result1.setData(System.currentTimeMillis() - startTime);
        return result1;
    }
    /**
     * 批量添加新的對象
     * @return
     */
    @RequestMapping(value = "/batAddList", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Object batAddList(){
        Result result ;
        long startTime =  System.currentTimeMillis();
        String content = startTime + "";
        List<Result> resultList = new ArrayList<>(1000);
        for (int i=10001;i<=1010000;i++){
            result = new Result();
            result.setId(i);
            result.setContent(content);
            resultList.add(result);
            if (resultList.size() == 1000){
                mongoResultService.insertResultBatch(resultList);
                resultList.clear();
            }
        }
        ApiResult result1 = new ApiResult();
        result1.setData(System.currentTimeMillis() - startTime);
        return result1;
    }
}

注:ApiResult 是內部封裝的向前端響應的實體對象,主要有三個變量:code,msg,data

AppStart.java

@SpringBootApplication
@EnableAutoConfiguration
public class AppStart {
    public static void main(String[] args) {
        SpringApplication.run(AppStart.class,args);
    }
}

測試結果

-- mongodb
-- 單條插入1000條
{
    "code": "1",
    "msg": "",
    "data": 5025
}

-- 單條插入100萬條
{
    "code": "1",
    "msg": "",
    "data": 1230669
}
-- 清除歷史數據
-- 批量插入1000條
{
    "code": "1",
    "msg": "",
    "data": 26
}
-- 批量插入1萬條
{
    "code": "1",
    "msg": "",
    "data": 255
}
-- 批量插入100萬條
{
    "code": "1",
    "msg": "",
    "data": 25650
}

 

數據統計

累計入庫總記錄數

測試庫總大小

 

總結

        100萬條記錄一條一條的插入到數據集合中,須要耗時約 20分鐘 =(1230669/ 1000 / 60),入庫速度偏慢;

        100萬條記錄每1000條爲一批的方式插入到數據集合中,須要耗時約 25秒 = (25650/ 1000),速度很快;

        涉及到大批量數據插入到數據庫集合中,建議因採用批量插入方式,才能發揮數據庫的最大潛力,在特殊的業務場景上,若是插入操做多,讀入操做少,能夠採用隊列的方式,先收集數據緩存(如緩存內存中,redis等),當隊列達到必定量後,再批量插入到數據庫中(要求實時性強,數據重要等除外);

相關文章
相關標籤/搜索