Search code examples
.netlinqsql-server-2008linq-to-entities

What LINQ operation related to Paging could be slowing down my query?


I've written a pretty generic LINQ query which is used throughout my app and works very well for all cases but one. I'm only running SQL Express at the moment so can't jump into sql profiler until my download completes, so until then, is there something that stands out in my following LINQ that is going to cause a massive slow down?

Below is a summary of what gets executed. The hold up is of course on the ToList call, and takes a good 30 seconds. I use this code for all my grid views, and only one has the hold up on it. MyGridView is a sql view and in the problem data takes only 2 seconds to execute and return all 16417 records through Sql Management Studio. Finally, it only takes this long when I request pages near the end of the data, so I am assuming it is some how related to the Take and Skip implementation.

private void Demo()
{
    // using LINQ To Entity...
    using (var entities = new MyEntities())
    {
        int page = 1641;
        int pageSize = 10;

        IQueryable<MyGridView> results = entities.MyGridView;

        results = results.Where(r => r.DeletedDate == null);

        var resultCount = results.Count();

        results = ApplyPaging(results, page, pageSize);

        // On the problem data, ToList takes a good 30 seconds to return just 10 records
        var resultList = results.ToList();
    }
}

private IQueryable<T> ApplyPaging<T>(IQueryable<T> data, int currentPage, int pageSize)
{
    if (pageSize > 0 && currentPage > 0)
    {
        data = data.Skip((currentPage - 1) * pageSize);
    }
    data = data.Take(pageSize);
    return data;
}

Anything jump out as being bad, wrong, dangerous? When I get a copy of profiler installed I'll try and go through the generated sql and post if I find any hints there.


Solution

  • See http://msdn.microsoft.com/en-us/library/bb357513.aspx#1

    Skip method is very useful with LINQ to SQL to organize server-side results paging, and some more things. But there are performance issues in some cases, because LINQ can build too difficult SQL queries from specified LINQ expressions. I touched this problem with MS SQL Server 2008. (...)

    (...) if there are 1000000 records in the Orgs table this query will be executed very long time because DB server will sort records in memory (unlikely you have an appropriate index with all columns ordering). And even so simple query

    orgs.Skip(10).Count() requires a significant amount of time, while

    orgs.Count()-10 performes much more quickly :)

    Perhaps that's the root of the problem.