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

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()分析查询计划,确认索引使用情况。检查集合文档数量,考虑分片策略。

