[Update] 6/16/2022:
1. The Introduction to TPC in Entity Framework 7 is a game-changer
Watch this video to understand more.
2. OrderBy should be conducted on an Index column e.g. OrderBy(Id). Sometimes you find yourself ordering on the Created Date which happens to be a none-index Column. This has performance implications.
3. Avoid very wide Tables, retrieving data from a wider table is slower than a less wide table.
When to use AsNoTracking() and how to optimize Entity Framework for performance
1. Think about what data you need or you might need in the future and select only the data that is needed. Avoid the bad practice of just selecting all the data inside a table, this will hurt the performance of the application, instead of identifying the columns and data needed for the operation to take place.
2. If possible, use IQuerrible to able to sort and filter the data, that way it won't be only one set of datasets needed for a page to load
3. Identify code Hot Path, (instruction the app executes while it returns the response) and optimize for performance. This includes the data that is returned.
If possible do your complex computation and calculations and store them in the database. This can be achieved by scheduling a job that mainly deals with Calculations and inserting them into the table.
This way, the Hot Path can only do the "reads" and is able to return the response as quickly as possible. With the coming of Http/3, this might not be an issue, but it does not hurt to optimize for performance.
5. Use AsNoTracking() only when you don't need to update the data at some point.
For example:
If you're only reading from the database and sending the data to the UI and not doing immediate updates, this way it is okay to use AsNoTracking(). However, if you retrieve data using AsNoTracking() somewhere in your Linq query and then you try to modify the data (entities) then that way you are doing something wrong.
[NB] It takes longer to query the data using AsNoTracking() and then modify the data than just not using AsNoTracking() because that way if you want to modify the data, the Entity Framework will track all records and try to speed up the updates (Updates happens in ranges).
6. Never call _context.SaveChanges() inside a for-loop or a foreach-loop. Calling the database in O(n) might slow down your application. Instead, do the operations on the records retrieved from the database and then call _context.SaveChanges() outside the loop.
This way the operation will run faster and when it comes time to save changes using _context.SaveChanges() outside the loop, EF Core 5 would have tracked all the changes inside a loop and then commits only once.
Overall Application Performance Tuning
1. Run Performance Profiler Analysis on your application and see the performance report.
- You should always strive for less Garbage Collection in your application.
- Pay attention to how you allocate memory or the way you create objects. Minimize Object creation outside Methods/functions as these objects get created globally and might cause a GC to happen.