patterncsharpModerate
Entity Framework Skip and Take too slow
Viewed 0 times
takeskiptooslowandframeworkentity
Problem
The following code achieves what I require, reading 10000 rows at a time:
Is there an alternative which will make this faster?
Here's the full code:
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.
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.