-
Type: Bug
-
Resolution: Done
-
Priority: Critical - P2
-
None
-
Affects Version/s: 2.7.3
-
Component/s: Performance
-
None
I noticed this in our system. Our code was using a lot of CPU even when not "much" was going on. After some investigation i nailed it down to the short code snippets below.
I'm using MongoDB C# driver 2.7.2.
Both collections used have around 6k-10k documents in em.
I see around 8-10% of CPU consumption when i use the code below:
IMongoDatabase MyTenantMongoDatabase = MongoDB.MongoDatabase.Get(connectionString, "database"); FindOptions MyFindOptions = new FindOptions(); MyFindOptions.NoCursorTimeout = true; //This can be a long running operation, so we don't want any timeouts! await MyTenantMongoDatabase.GetCollection<BsonDocument>("collection") .Find(new BsonDocument(), MyFindOptions) .ForEachAsync(async document => { String MyLeftValue = document.GetValue("fieldX", String.Empty).AsString; String MyRightValue = document.GetValue("fieldY", String.Empty).AsString; FilterDefinition<BsonDocument> MyLeftObjectFilter = MyLeftObjectFilter = Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.Eq("is_deleted", false), Builders<BsonDocument>.Filter.Eq("title", MyLeftValue)); FilterDefinition<BsonDocument> MyRightObjectFilter = MyLeftObjectFilter = Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.Eq("is_deleted", false), Builders<BsonDocument>.Filter.Eq("title", MyRightValue)); FilterDefinition<BsonDocument> MyCountFilter = Builders<BsonDocument>.Filter.Or(MyLeftObjectFilter, MyRightObjectFilter); Int64 MyObjectNeededForRelationCount = await MyTenantMongoDatabase.GetCollection<BsonDocument>("othercollection") .CountDocumentsAsync(MyCountFilter); });
When i change it to the code snippet below i see around 0,5-1,5% of CPU consumption:
IMongoDatabase MyTenantMongoDatabase = MongoDB.MongoDatabase.Get(connectionString, "database"); FindOptions MyFindOptions = new FindOptions(); MyFindOptions.NoCursorTimeout = true; //This can be a long running operation, so we don't want any timeouts! await MyTenantMongoDatabase.GetCollection<BsonDocument>("collection") .Find(new BsonDocument(), MyFindOptions) .ForEachAsync(document => { String MyLeftValue = document.GetValue("fieldX", String.Empty).AsString; String MyRightValue = document.GetValue("fieldY", String.Empty).AsString; FilterDefinition<BsonDocument> MyLeftObjectFilter = MyLeftObjectFilter = Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.Eq("is_deleted", false), Builders<BsonDocument>.Filter.Eq("title", MyLeftValue)); FilterDefinition<BsonDocument> MyRightObjectFilter = MyLeftObjectFilter = Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.Eq("is_deleted", false), Builders<BsonDocument>.Filter.Eq("title", MyRightValue)); FilterDefinition<BsonDocument> MyCountFilter = Builders<BsonDocument>.Filter.Or(MyLeftObjectFilter, MyRightObjectFilter); Int64 MyObjectNeededForRelationCount = MyTenantMongoDatabase.GetCollection<BsonDocument>("othercollection") .CountDocuments(MyCountFilter); });
So the change is to not use the async & await on Count in the ForEachAsync. This is a simplified version, in my other code i see a drop from 15-24 => 0,5 - 2.
If it's not clear please let me know!