redlaz
redlaz

Reputation: 121

Entity Framework insertion performance

Im testing using Entity Framework with a Azure Sql db. When inserting 1 record, the action takes 400ms. When adding 20 it is 2500ms.

400ms for inserting 1 record via EF seems like a lot.

What is the normal performance rate for EF?

Am I doing something wrong?

Im aware that bulk insertion can be improved, but I thought that a single insert could be done a lot faster!?

var start = DateTime.Now;
testdbEntities testdbEntities = new testdbEntities();

for (int i = 0; i < 20; i++)
    testdbEntities.Users.Add(new User{Name = "New user"});

testdbEntities.SaveChanges();

var end = DateTime.Now;
var timeElapsed = (end - start).TotalMilliseconds;

Upvotes: 3

Views: 993

Answers (4)

Jonathan Magnan
Jonathan Magnan

Reputation: 11337

All common tricks like:

  • AutoDetectChangesEnabled = false
  • Use AddRange over Add
  • Etc.

Will not work like you already have noticed since the performance problem is not within Entity Framework but with SQL Azure

SQL Azure may look pretty cool at first but it's slow as hell unless you paid for a very good Premium Database Tier.

As Evk recommended, you should try to execute a simple SQL Command like "SELECT 1" and you will notice this probably take more than 100ms which is ridiculously slow.

Solution:

  • Move to a better SQL Azure Tier
  • Move away from SQL Azure

Disclaimer: I'm the owner of the project Entity Framework Extensions

Another solution is using this library which will batch multiple queries/bulk operations. However again, even if this library is very fast, you will need a better SQL Azure Tier since it look every database round-trip take more than 200ms in your case.

Upvotes: 3

Ketan
Ketan

Reputation: 262

Most EF applications make use of persistent ignorant POCO entities and snapshot change tracking. This means that there is no code in the entities themselves to keep track of changes or notify the context of changes.

When using most POCO entities the determination of how an entity has changed (and therefore which updates need to be sent to the database) is handled by the Detect Changes algorithm. Detect Changes works by detecting the differences between the current property values of the entity and the original property values that are stored in a snapshot when the entity was queried or attached.

Snapshot change detection takes a copy of every entity in the system when they are added to the Entity Framework tracking graph. Then as entities change each entity is compared to its snapshot to see any changes. This occurs by calling the DetectChanges method. Whats important to know about DetectChanges is that it has to go through all of your tracked entities each time its called, so the more stuff you have in your context the longer it takes to traverse.

What Auto Detect Changes does is plugs into events which happen on the context and calls detect changes as they occur.

Whenever you are adding a new User object, EF is internally tracking it & keeping the current state of newly added object in its snapshot. For bulk insert operations, EF will first insert all records into the DB & then call DetectChanges function. So execution time required for bulk insert is (time required to insert all records + time required for updating EF context).

You can make your DB insertion relatively faster by disabling AutoDetectChanges. So your code will look like,

using (var context = new YourContext()) 
{ 
    try 
    { 
        context.Configuration.AutoDetectChangesEnabled = false; 

        // do your DB operations
    } 
    finally 
    { 
        context.Configuration.AutoDetectChangesEnabled = true; 
    } 
}

Upvotes: 0

Satya_MSFT
Satya_MSFT

Reputation: 1022

Each insert results in a commit and causes log harden (flush to disk). In case of writing in batches this may not result in one flush per insert (until log buffers full). So try to batch the results somehow, for example using TVFs

Upvotes: 1

devGirl
devGirl

Reputation: 58

You can disable the auto detect changes during your insert. It can really improve performance. https://msdn.microsoft.com/en-us/data/jj556205.aspx

I hope it helps :)

Upvotes: 0

Related Questions