I found a very interesting in page: http://msdn.microsoft.com/en-us/library/cc853327.aspx
Here you can see during query stages, there is an stage named "Generating views" will cost a lot. Even though EF provides some method to pre-compile it, but if you have many query without pre-compile you still may get problems.
You can find How to: Pre-Generate Views to Improve Query Performance here: http://msdn.microsoft.com/en-us/library/bb896240.aspx
And here, you can see query without pre-generate will cost twice time. So that means it does cost a lot. http://blogs.msdn.com/b/appfabriccat/archive/2010/08/06/isolating-performance-with-precompiled-pre-generated-views-in-the-entity-framework-4.aspx
So I have a question, why EF design this stage? And does NHibernate also have this stage? If true, how about it performance in Nhibernate?
EF views have nothing to do with SQL views - EF views are mapping transformation compiled into executable code. EF use these transformation to convert its query representation into target SQL representation. The reason for this compilation is performance of the whole application - you need to invest time to initialization but all your subsequent queries and updates will use compiled code instead of some lookup in EDM. If you don't need to modify mapping at runtime you can even pre-compile those views during compilation of your application.
EF views are used for query preparation (transforming one representation into another) but the query preparation must be done for each unique query. In EF 4 this preparation is not cached unless you manually use Compiled query. In EF 4.5 and 5.0 (.NET 4.5) all queries are automatically "compiled" = there is the cache and each unique query is really prepared only once. Subsequent execution of the same query use compiled version from the cache.
You can read more about performance and EF 5.0 in this beginner guide.
Related
I'm experiencing some performance issues with EF and was wondering... well ... why.
The query I am running is simply:
var procs = ctx.Procedures
.Include(p => p.ProcedureProcedureFields.Select(ppf => ppf.ProcedureField))
.Where(p => p.IsActive)
.Where(p => !p.ProcedureLogbookTypes1.Any()).ToList();
So, not even passing in any parameters, which rules out a out of the issues. If I take the SQL from SQL Profiler and run it directly in SSMS, it takes less than 1s.
The EF call takes about 12s for the procs variable to be populated.
A few more things.
I have not just run the sql after the EF for comparison. I've made sure that there was no plan in cache. In fact, I've done both. I've run the SQL when a plan is in cache and when not. Any and every combination of running the 2 things yields the same results. The raw SQL is a fraction of the time of the EF query.
I'm all for using Stored Procedures where the query is uber-complex and the requirement for customizing the SQL is required for performance.
But the query above is simple. The SQL generated is simple.
I'd rather not litter my database with a million little stored procs, just because I cannot figure out how to make EF perform.
Is there a way to speed this up?
Thanks
You can use AsNoTracking as described by this answer (which is sourced from this article):
Entity Framework exposes a number of performance tuning options to help you optimise the performance of your applications. One of these tuning options is .AsNoTracking(). This optimisation allows you to tell Entity Framework not to track the results of a query. This means that Entity Framework performs no additional processing or storage of the entities which are returned by the query. However, it also means that you can't update these entities without reattaching them to the tracking graph.
I would like to ask the Entity Framework Core team what their ambition is for the scope/complexity of query translation compared to EF6.
I've used EF6 extensively and I know that if you can express it in LINQ and don't use any untranslatable functions, EF can probably translate the query correctly.
Will Entity Framework's translation be eventually as good as that, or is that something that is considered secondary, like the lazy loading feature.
If so, about what is the team eventually aiming at compare to EF6?
There's a ticket discussing GroupBy that appears to indicate they deem grouping an advanced type of query, but compared to what EF6 can translate, a normal group-by is pretty average.
(I'm asking here as the EF Core team says on it's site it is monitoring SO for questions.)
We took a very different approach in EF Core. Every LINQ query should work--even if you use untranslatable functions. We do this by translating the parts of the query we can into SQL and processing the rest on the client after the results are returned by the server. As EF Core evolves, we'll translate more and more of the query into SQL (e.g. GROUP BY) which can make it more efficient.
In theory, our goal is to translate everything that the store supports. In some cases however (especially on NoSQL stores) there simply is no translation for a LINQ operator, and we feel it's better to be functional and inefficient than to throw.
If you want to ensure your whole query is translated, you can disable client evaluation. This will cause it to throw like EF6.
I'm bit confused: with all the evolutions of EF i'm not sure where i'm now.
*Is EDMX a choice of the past and should be used any more ?
*If so what is the best choice ?
*I hate edmx, can i upgrade to code first ?
It is not clear what all this EF versions are to me
Thanks
Jonathan
For a lot of apps you can start using Code First if you want to. The one big thing Code First doesn't support yet is mapping to stored procedures. (You can still call stored procedures, but you can't map entity CRUD operations to them.)
That being said, doing Database First with an EDMX is still absolutely supported and a fine choice, especially you like using the EF designer.
EF 4.1 and above fully support both Code First and Database First.
Personally, I would almost always choose Code First, even with an existing database, because I'm a code-centric person and would rather keep all my mappings in code where I can easily refactor, manage in source control, split into multiple files, etc. For me, it's much easier and nicer to deal with code artifacts than monolithic XML documents.
This is how you should evaluate your Entity Framework usage:
1) EDMX is a totally valid option specifically if you have an existing Database and want to generate your entities based on your database schema. One of my favorite benefits to this can be rapid data layer development with low risk. Also mapping stored procedure results to classes is always nice when you have complex existing stored procedures to work with.
OR
2) Code First is a totally valid option specifically if you want to create you database based an object oriented data model. With code first its easy to make big refactors that you don't always think of till implementation time. Source control is more common with code and shelving/rolling back are beautiful features.
TL;DR version :
They are both totally viable options. Neither are outdated ;nor shall they be any time soon.
We had performance consideration in warm up EF Code First. EF Code First take some minutes to start, because we have thousand Entity. so this bottleneck enforced us to Use EDMX, and used Interactive Pregenerated to Create EDMX from Code First in First Run after entity Model changed, and at Other First Run warm up time considerably lowered.
but story not end at that. after doing that we saw in Development area we have many change in Entity Model, so after each change EDMX File should be recreated(update) very often. so we decide to Create EDMX Programatically and Optimize that creation for our Entity Models.
I am starting with the Entity Framework. It sounds great. But I am wondering if I should watch out for some weakness somewhere. Any experience there?
You probably need to start prefixing these questions with the version you are talking about. A good amount of the annoyances have been fixed in the upcoming version in .NET 4.0.
Here is what I would say after working with the first version for about 6 months using a decent size DB in sql 2k8(40+ tables, several tables with close to 1M rows, and decent amount of traffic)
Lack of Foreign key properties. Meaning if I want to know or work with just the id of a related table I have to load the actual entity. (fixed in next version)
Utter lack of an easy outer join like linq to sql has when using DefaultIfEmpty. Fixed in next version.
Generated Sql is less than optimal This seems to be fixed in next version as well
Very difficult to abstract from your code for testability and for use in multi tiered environments, but it can be done. This can also be classified as the POCO problem that also has been resolved.
There are more, but these are my top ones.
Overall I would use it again, but if you are starting from scratch please save yourself some pain and wait for the latest version or start using the beta if you can.
You might find the walkthroughs for Entity Framework 4.0 useful. All of the new features discussed are annoying emissions from the currently released version for someone.
I found the new TDD/testability features and T4 code generation features especially interesting.
About EF1:
Generated SQL is horrible. It multiples joins, it is 10x bigger than it could. I had a simple query, but with a lot of joins and generating this query by EF (not executing) was slowing down significantly my application. No, I couldn't use precompiled query. I used view to cope with it. SQL Profiler was helpful.
Primary keys in views are not recognized properly. You have to change edmx file by hand when you import view or doing schema refresh.
You can design entities from database in graphical manner, update model from database, but it doesn't always work good, specially when you change field types or foreign keys.
You can't update one table in model, always have to update whole model from db.
You can't define base class for your entities, it is already defined (EntityObject). You can use interfaces, because classes are defined as partial.
No POCO, entity classes are strongly connected to framework.
You can set foreign key by EntityReference.EntityKey, but when you have EntityCollection, prepare for round trip to db. Or am I missing something?
I am finding the POCO objects and model-first design in the EF4 beta very sexy.
I am using Entity Framework to layer on my SQL Server 2008 database. The EF is present in my web service and the webservice is invoked by a Silverlight client.
I am seeing a serious performance issue in terms of the duration taken by a query to execute in the EF. This wouldn't happen in the consecutive calls.
A little bit of googling revealed that, it's caused per app domain to construct the in-memory model of the db objects. I found this Microsoft link explaining pre-generation of views for performance improvement. Even after implementing the steps, the performance actually degraded instead of improving. I am curious, if anyone has tried this approach successfully and if there are any other avenues for improving performance.
I am using .NET 3.5.
A couple areas to look at for EF performance
Do as much of the processing before calling things like tolist(). ToList will bring everything in the set into memory. By default, EF will keep building the expression tree and only actually process it when you need the data in memory. That first query will be against the database, but afterwards the processing will be in memory. When working with large data, you definitely want as much of the heavy lifting done by the database as possible.
EF 1 only has the option to pull the entire row back. Therefore if you have a column that is a large string or binary blob, it is going to be pulled down and into memory whether you need it or not. You can create a projection that doesn't include this column, but then you don't get the benefits of having it be an entity.
You can look at the sql generated by EF using the suggestion in this post
How do I view the SQL generated by the Entity Framework?
The same laws of physics apply for EF queries as they do for ordinary SQL. Check your database tables and make sure that you have indexes on primary and foreign keys, that your database is properly normalized, and so forth. If performance is degrading after Microsoft's suggestions, then that's my guess as to the problem area.
Are you hosting the webservice in IIS? Is it running on the same site as the Silverlight App? What about the database itself? Is it running on a dedicated machine? Are there other apps hitting it? The first call to a dormant database is painful (I've had situations where it would actually time out in my environment.)
There are a number of factors to take into consideration here. But it comes down to more than just EF's overhead.
edit I didn't fully qualify but the process of opening the first connection to SQL Server is slow regardless of your data access solution.
Use SQL Profiler to check how many queries executed to retrieve your data.If it's large number use Include() method of ObjectQuery to retrieve child objects with parent in one query.