Golang MongoDB查询性能优化问题探讨

Golang MongoDB查询性能优化问题探讨 执行一个简单的查询需要大约980.9938毫秒到2秒的时间。

这是我的函数

image

3 回复

感谢您的回复,我已经修复了问题,确实是 bcrypt 的原因,谢谢大家 😉 我将 bcrypt 的 salt 从 14 改为了 10。

更多关于Golang MongoDB查询性能优化问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


也许问题不在于MongoDB查询,在你的基准测试步骤中加入更多日志。

如果你的CheckPasswordHash函数使用了bcrypt算法,那么密码比较可能会耗费时间。https://stackoverflow.com/questions/15763086/bcrypt-for-password-hashing-because-it-is-slow

针对查询性能问题,以下优化方案可供参考:

1. 索引优化

确保查询字段已建立索引:

// 创建复合索引
_, err := collection.Indexes().CreateOne(context.Background(), mongo.IndexModel{
    Keys: bson.D{
        {Key: "user_id", Value: 1},
        {Key: "status", Value: 1},
        {Key: "created_at", Value: -1},
    },
})

2. 查询优化

限制返回字段并添加查询提示:

opts := options.Find().
    SetProjection(bson.D{
        {Key: "_id", Value: 1},
        {Key: "title", Value: 1},
        {Key: "created_at", Value: 1},
    }).
    SetSort(bson.D{{Key: "created_at", Value: -1}}).
    SetLimit(20).
    SetHint("user_id_1_status_1_created_at_-1")

cursor, err := collection.Find(ctx, filter, opts)

3. 连接池配置

优化MongoDB客户端配置:

clientOptions := options.Client().
    ApplyURI(uri).
    SetMaxPoolSize(100).
    SetMinPoolSize(10).
    SetMaxConnIdleTime(30 * time.Second).
    SetSocketTimeout(2 * time.Second)

client, err := mongo.Connect(context.Background(), clientOptions)

4. 批量查询优化

使用聚合管道减少网络往返:

pipeline := mongo.Pipeline{
    {{Key: "$match", Value: filter}},
    {{Key: "$sort", Value: bson.D{{Key: "created_at", Value: -1}}}},
    {{Key: "$limit", Value: 20}},
    {{Key: "$project", Value: bson.D{
        {Key: "_id", Value: 1},
        {Key: "title", Value: 1},
        {Key: "created_at", Value: 1},
    }}},
}

cursor, err := collection.Aggregate(ctx, pipeline)

5. 监控查询性能

添加查询执行时间监控:

start := time.Now()
cursor, err := collection.Find(ctx, filter, opts)
elapsed := time.Since(start)

if elapsed > 500*time.Millisecond {
    log.Printf("Slow query detected: %v", elapsed)
    explain, _ := collection.Find(ctx, filter, opts.SetExplain(true))
    log.Printf("Query plan: %v", explain)
}

6. 使用游标批处理

优化大数据集处理:

cursor, err := collection.Find(ctx, filter, opts.SetBatchSize(100))

for cursor.Next(ctx) {
    var result bson.M
    if err := cursor.Decode(&result); err != nil {
        break
    }
    // 处理数据
}

执行explain()分析查询计划,确认索引使用情况。检查集合文档数量,考虑分片策略。

回到顶部