HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Entity Framework Skip and Take too slow

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
takeskiptooslowandframeworkentity

Problem

The following code achieves what I require, reading 10000 rows at a time:

var query = repository.Subscribers.ToList().Skip(numberToSkip).Take(numberInBatch);


Is there an alternative which will make this faster?

Here's the full code:

protected static string ContactUrl = BaseUrl + "/api/contact";  

protected static int NumberInBatch = 10000;
protected static int NumberToSkip = 10000;
protected static int NumberToCountUpto = 100000;

public static string GetSubscribers(int numberToSkip, int numberInBatch)
    {
        using (var repository = new SubscriberEntities())
        {
            var index = 0;
            string output = null;
            var query = repository.Subscribers.ToList().Skip(numberToSkip).Take(numberInBatch);

            foreach (var subscriber in query)
            {
                var telephone = ContactHelper.GetTelephoneFromEmail(subscriber.EmailAddress);

                string requestCreateContact = RequestHelper.CreateContact(subscriber.EmailAddress, telephone);
                if (index > 0) output = output + ",";
                output = output + (requestCreateContact);

            }
            return output;
        }
    }

    //Batch Create
    public static void SendBatchCreate()
    {

        for (int i = NumberToSkip; i < NumberToCountUpto; i += NumberInBatch)
        {
            var requestCreateMultipleContacts = GetSubscribersAndCreateContacts(i, NumberInBatch);

            RequestHelper.SubmitPostRequest(requestCreateMultipleContacts, ContactUrl);
        }
        Console.ReadKey();
    }

Solution

I would first suggest logging the database operation to see what SQL is executed. EF may not be running the SQL you think it is.

The red flag I see is that you call ToList before the Skip and Take. Generally in LINQ statements, ToList forces execution immediately.

This suggests your EF code is pulling every record from the table up front, building a list, and then applying the Skip/Take to the list. If that's the case, the logged SQL should show a select statement without any filtering.

I suspect what you really want to do is run the ToList after the Skip and Take. This should apply the filtering inside the executed SQL, but the logging will show you for sure.

Context

StackExchange Code Review Q#46940, answer score: 16

Revisions (0)

No revisions yet.