Details
-
Bug
-
Resolution: Done
-
Critical - P2
-
None
-
2.7.3
-
None
Description
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!