go获取mongo数据再导出excel文件的效率问题

先看图吧...

82.5w条数据处理结束得2周,这时间还在增加...

CPU是i5-9400,16G DDR4 2666,数据库是局域网内的服务器,从数据库上读数据花不了啥时间,存的很慢...

数据处理部分简略了,大概情况是获取到数据后先解析回存入数据库时的数据类型,然后在NewExcelData()这类方法里筛选出来了其中需要的数据部分,最后输出的数据大概占数据库单条数据的1/20的样子。

部分代码:

import (
    "github.com/cheggaaa/pb"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "github.com/xuri/excelize/v2"
)

func Save2Excel(sheetName string, v interface{}, lineNum int) (r error) {
    err := excelFile.SetSheetRow(sheetName, "A"+strconv.Itoa(lineNum+1), v)
    excelFile.Save()
    if err != nil {
        fmt.Println(v)
    }
    return err
}

documentCount := GetCount(coll)
fmt.Println("共", documentCount, "条数据")

// 单次从数据库中读取1w条数据
dataLimit := int64(10000)  

// 算下得循环多少次才能给数据读取完成
dataLoop := documentCount / dataLimit 
if documentCount%int64(dataLimit) != 0 {
    dataLoop += +1
}

// 依序完成所有数据的读取
for i := int64(0); i < dataLoop; i++ {
    // 从数据库中依次读取对应条数的数据
    // (collection, fliter, 单次读取的数据量限制, 跳过前x条数据)
    results := FindNextLimit(coll, bson.D{}, dataLimit, i*dataLimit)
    // 处理数据
    for i := 0; i < len(results); i++ {
        printCount++
        bar.Increment()

        resultData, _ := bson.Marshal(results[i])

        var rawData RawDataType
        bson.Unmarshal(resultData, &rawData)

        Save2Excel("Sheet1", NewExcelData(rawData), printCount)
    }
}
bar.Finish()
fmt.Println("导出完成")

这个效率是正常的还是我代码哪里写的有问题...请教下相关大佬

153 views
Comments
登录后评论
Sign In
·

应该是哪里 IO 耗时过大了,不要循环太多次,先试试 100 次,打时间戳统计各个步骤耗时:

import time
print(time.time_ns())

调试出具体耗时长的语句。

·

编码习惯:for 语句不带计算,小小优化一下:

for i := 0; i < len(results); i++ {

改为:

resultsLen = len(results)
for i := 0; i < resultsLen; i++ {
·

结案了,写入一条数据保存一次这到后面数据多了能不慢吗...

改进:

func Save2Excel(sheetName string, v interface{}, lineNum int) (r error) {
    err := excelFile.SetSheetRow(sheetName, "A"+strconv.Itoa(lineNum+1), v)
    // excelFile.Save()  删除此行
    if err != nil {
        fmt.Println(v)
    }
    return err
}

for i := int64(0); i < dataLoop; i++ {

    excelFile.Save() // 处理完一组数据后保存一次

    // 从数据库中依次读取对应条数的数据
    // (collection, fliter, 单次读取的数据量限制, 跳过前x条数据)
    results := FindNextLimit(coll, bson.D{}, dataLimit, i*dataLimit)
    // 处理数据
    resultsLen = len(results)
    for i := 0; i < resultsLen; i++ {
        printCount++
        bar.Increment()

        resultData, _ := bson.Marshal(results[i])

        var rawData RawDataType
        bson.Unmarshal(resultData, &rawData)

        Save2Excel("Sheet1", NewExcelData(rawData), printCount)
    }
}