Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I lose performance if I use LINQ on MongoDB?

This is the situation. I have a Domain object Product like this...

[DataContract]
public class Product : IStorableEntity
{
    [DataMember]
    public String Id { get; set; }
    [DataMember]
    public String RemoteId { get; set; }
    [DataMember]
    public String LanguageId { get; set; }
    [DataMember]
    public DateTime? CreationDate { get; set; }
    [DataMember]
    public DateTime? LastUpdate { get; set; }
    ETC..ETC...
}

into my repository layer I have the following method.

public IEnumerable<TElement> Read()
{
    var mongoCollection = _mongoDatabase.GetCollection<TElement>(_partitionName);
    return mongoCollection.AsQueryable<TElement>();

}

With this method I want to expose via LINQ my repository layer without exporting information about technology.

In this way I can do this:

var _repository = new MyRepositoryFactory<Product>(); 
var result = _repository.Read().Where(p=>p.RemoteId == "1")

this query it takes 1 or 2 milliseconds.

instead...

var _repository = new MyRepositoryFactory<Product>();
var result = _repository.Read().Where(p=>p.RemoteId == "29000")

it takes 2800 milliseconds!!!

I have correctly created a unique index with the command

db.products.ensureIndex({"RemoteId":1, unique:true})

NB: Yes, I have also rebuilt the indexes with .reIndex() command

Here the strange thing... Avoiding LINQ and modifying the repository method in...

public IEnumerable<TElement> Read(string remoteId)
{
    var mongoCollection = _mongoDatabase.GetCollection<TElement>(_partitionName);
      var query = Query<TElement>.EQ(p => p.RemoteId, remoteId);
    return mongoCollection.Find(query);
}

if then I invoke the method whit the same id before..

var _repository = new MyMongoRepository<Product>();
var result = _repository.Read("29000")

it takes 1 or 2 milliseconds. WHY??

Why with the first approach do I have a performance degradation as the id increases instead with the second is not it?

Ps. Erm... really sorry for my english

like image 448
Payedimaunt Avatar asked May 08 '13 21:05

Payedimaunt


People also ask

Can we use LINQ with MongoDB?

With Language Integrated Queries (LINQ), we can use an established and well known C# syntax to work with our MongoDB documents and data.

Is using LINQ good?

The LINQ architecture is good - but some may prefer to read source code that does not use the LINQ SQL-like syntax. So if you're strict on readability, you may want not to use that syntax. Readability is not that big issue.

Is LINQ slow?

It is slightly slower LINQ syntax is typically less efficient than a foreach loop. It's good to be aware of any performance tradeoff that might occur when you use LINQ to improve the readability of your code. And if you'd like to measure the performance difference, you can use a tool like BenchmarkDotNet to do so.


1 Answers

As WiredPrainie stated in comments you should use IQueryable instead of IEnumerable otherwise the whole collection will be retrieved. Read this guide carefully http://docs.mongodb.org/ecosystem/tutorial/use-linq-queries-with-csharp-driver/

like image 100
asm Avatar answered Sep 19 '22 13:09

asm