ADO.NET Entity framework model Performance - c#

I saw similar questions around the same topic, but i couldn't solve my issue.
I have asp.net web application with DB2 backend. And we have the entity framework model 3.5
So when i load the page for the very first time, it takes close to 15 seconds for executing the first query. And the query is very simple, selecting a row from one table and the where clauses are indexed. This is the query
protected Detail getProgramDetail(string id1,string id2, string id3)
{
Detail result = (from d in context.Detail
where d.id1.equals(id1) &&
d.id2.equals(id2) &&
d.id3.equals(id3)
select d).FirstorDefault();
return result;
}
I tried updating the statistics too, but it didnt help either.
After reading other performance tuning articles, i made this query as a compiled one, but still its taking close 15 seconds. But the subsequent calls are pretty fast in milliseconds. I think its taking time to establish the connection and run the query.
Is there a way to improve the initial performance?. I tried to generate views. But i am receiving the below error. Not sure how to handle this one.
The specified store provider cannot be found in the configuration, or
is not valid
My connection string is in machine.config.
Thanks in advance.
Srividhya

Is there a way to improve the initial performance?.
What about it is not ASp.NET / Entity Framework but IIS - STARTING THE APPLICATION, including doing the compilation needed ;)?
Make it hot - there is an extension that can call a page when IIS starts, so the applicatin is hot (compiled, loaded in memory).
http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx

There are multiple options which you look forward for solving this issue
1) Add the second level caching with the Entity framework .This article is very helpful
http://msdn.microsoft.com/hi-in/magazine/hh394143(en-us).aspx
2) Querying and ORM dont stick together very well ,Can you use a stored procedure and Datareader which will definitely optimize performance.
3)If you can use Optimize the first or default in your code

Related

How to optimize performance of .net 5 application when working with mysql using Entity Framework Сore

My .net 5 application uses mysql database.
The work is done using the ORM Entity framework Core 5.0.11 and Pomelo.EntityFrameworkCore 5.0.2
Recently, I've been thinking about query performance.
The same query sent with applications and directly with mysql client (used workbench) has different execution time.
As a rule, requests from the workbench are executed two / three times faster.
Example:
_dbContext.SharepointFile.Create(
new SharepointFile
{
SharepointFileId = driveItem.Id,
EmbedUrl = model.Link,
Hash = hash,
});
await _dbContext.SaveAsync();
Converted to a query like:
INSERT INTO `SharepointFiles` (`EmbedUrl`, `Hash`, `SharepointFileId`)
VALUES (#p0, #p1, #p2);
SELECT `Id`
FROM `SharepointFiles`
WHERE ROW_COUNT() = 1 AND `Id` = LAST_INSERT_ID();
This request from the application completes in ~0.58 sec on average.
The same request sent from the Workbench client completes in ~0.2 sec.
Another example of a simple data fetch:
SELECT `s`.`Id`, `s`.`EmbedUrl`, `s`.`Hash`, `s`.`SharepointFileId`
FROM `SharepointFiles` AS `s`
WHERE `s`.`Hash` = #__hash_0
LIMIT 1
Runs from application in ~0.25 sec.
From workbench in ~0.065sec.
As you can see, these are simple, ordinary queries. Tell me what path to look for to optimize our application.
Perhaps there are thoughts about setting up a connection to mysql. I will provide details if needed.
When running a query in workbench will issue query against RDBMS and execute it there, so you're comparing after all running on the server to being apart, there will be difference.
That mentioned, when you do select, keep in mind if you need to modify data, and when not always use what Sebastian suggested with turning tracking off, see this performance piece on this,
https://www.c-sharpcorner.com/UploadFile/ff2f08/entity-framework-and-asnotracking/
.AsNoTracking()
you really should be doing this a lot and I'd suggest doing that and then see where you are, remember to measure first and I bet you can document already huge improvements, and You will have achieved a lot if asked to improve performance.
If wanting to do more, consider making procedures, they can be called from EF.Core even if that will work very well in terms of using the effeciency of one with databinding capabilites of the other e.g.
_context.Set<Model>().FromSqlRaw("CALL spProcedure({0});", parametervalue).ToList<Model>();

Removing entities in EF6 is very slow using RemoveRange

From reading many other posts it looks like I need to use
context.DbSet<Table>.RemoveRange(…);
context.SaveChanges();
to efficiently remove multiple entities.
Sadly however, in my scenario, this is still taking far too long. In tests, even removing 5 entities with about 10 fields takes about 1 sec per entity. This is far too slow.
What else can I do to improve performance?
Edit
This is what the method looks like that does the work:
public void RemoveClassReportGroupings(IEnumerable<(int clientClassId, int classReportGroupingId)> enumerable)
{
List<Class_ReportGrouping> removeItems = new List<Class_ReportGrouping>();
var dict = _context.ClassReportGroupings.Select(i => i).ToDictionary(i=> (i.ClassId, i.GroupingId));
foreach (var item in enumerable)
{
var removeItem = dict[(item.clientClassId ,item.classReportGroupingId)];
removeItems.Add(removeItem);
}
_context.ClassReportGroupings.RemoveRange(removeItems);
}
I guess, that this has nothing to do with EF, but with database optimization.
SaveChanges is the place where Entity Framework actually compiles your LINQ query into a suitable SQL query and executes it to the Database.
You may want to retrieve the query EF created for deletion for manual examination and or have a look at the possible query optimizations using a tool like MS SQL SQL Server Management Studio (SSMS)
There are plenty of resources about query analysis and optimizations for SQL server, have a look around these, e.g from Microsoft (retired, but still relevant)
I ran into a issue in slowness using RemoveRange() and discovered it had to do with how it translates those calls into sql statements. If I asked it to deleted 10 records. It would make 10 separate delete calls if you monitored thru SQL profiler or used some debugging code in your debugger to see the queries.
Ended up using dbcontext.executesqlcommand() to write a query that would delete those records all at the same time. Much quicker for our purposes. It can become a very big deal if you have a large amount of records.
Note - a byproduct of this was the local dbcontext will not be aware of those changes, so you may need to deal with those separately.
Also note - 1 second to delete 1 record seems like you may have some underlying db issues such as a large amount of referential integrities or some other constraint that forces the DB to do more then delete. As a rule I expect EF to perform very similar to how a raw sql command performs when executed directly on the server.
Old question but came up while I was trying to solve a similar problem. Maybe helps someone in the future.

Extremely slow and inefficient query execution from Entity Framework

I've got Entity Framework 4.1 with .NET 4.5 running on ASP.NET in Windows 2008R2. I'm using EF code-first to connect to SQL Server 2008R2, and executing a fairly complex LINQ query, but resulting in just a Count().
I've reproduced the problem on two different web servers but only one database (production of course). It recently started happening with no application, database structure, or server changes on the web or database side.
My problem is that executing the query under certain circumstances takes a ridiculous amount of time (close to 4 minutes). I can take the actual query, pulled from SQL Profiler, and execute in SSMS in about 1 second. This is consistent and reproducible for me, but if I change the value of one of the parameters (a "Date after 2015-01-22" parameter) to something earlier, like 2015-01-01, or later like 2015-02-01, it works fine in EF. But I put it back to 2015-01-22 and it's slow again. I can repeat this over and over again.
I can then run a similar but unrelated query in EF, then come back to the original, and it runs fine this time - same exact query as before. But if I open a new browser, the cycle starts over again. That part also makes no sense - we're not doing anything to retain the data context in a user session, so I have no clue whatsoever why that comes into play.
But this all tells me that the data itself is fine.
In Profiler, when the query runs properly, it takes about a second or two, and shows about 2,000,000 in reads and about 2,000 in CPU. When it runs slowly, it takes 3.5 minutes, and the values are 300,000,000 and 200,000 - so reads are about 150 times higher and CPU is 100 times higher. Again, for the identical SQL statement.
Any suggestions on what EF might be doing differently that wouldn't show up in the query text? Is there some kind of hidden connection property which might cause a different execution plan in certain circumstances?
EDIT
The query that EF builds is one of the ones where it builds a giant string with the parameter included in the text, not as a SQL parameter:
exec sp_executesql
N'SELECT [GroupBy1].[A1] AS [C1]
FROM (
SELECT COUNT(1) AS [A1]
...
AND ([Extent1].[Added_Time] >= convert(datetime2, ''2015-01-22 00:00:00.0000000'', 121))
...
) AS [GroupBy1]'
EDIT
I'm not adding this as an answer since it doesn't actually address the underlying issue, but this did end up getting resolved by rebuilding indexes and recomputing statistics. That hadn't been done in longer than usual, and it seems to have cleared up whatever caused the issue.
I'll keep reading up on some of the links here in case this happens again, but since it's all working now and unreproduceable, I don't know if I'll ever know for sure exactly what it was doing.
Thanks for all the ideas.
I recently had a very similar scenario, a query would run very fast executing it directly in the database, but had terrible performance using EF (version 5, in my case). It was not a network issue, the difference was from 4ms to 10 minutes.
The problem ended up being a mapping problem. I had a column mapped to NVARCHAR, while it was VARCHAR in the database. Seems inoffensive, but that resulted in an implicit conversion in the database, which totally ruined the performance.
I'm not entirely sure on why this happens, but from the tests I made, this resulted in the database doing an Index Scan instead of an Index Seek, and apparently they are very different performance-wise.
I blogged about this here (disclaimer: it is in Portuguese), but later I found that Jimmy Bogard described this exact problem in a post from 2012, I suggest you check it out.
Since you do have a convert in your query, I would say start from there. Double check all your column mappings and check for differences between your table's column and your entity's property. Avoid having implicit conversions in your query.
If you can, check your execution plan to find any inconsistencies, be aware of the yellow warning triangle that may indicate problems like this one about doing implicit conversion:
I hope this helps you somehow, it was a really difficult problem for us to find out, but made sense in the end.
Just to put this out there since it has not been addressed as a possibility:
Given that you are using Entity Framework (EF), if you are using Lazy Loading of entities, then EF requires Multiple Active Result Sets (MARS) to be enabled via the connection string. While it might seem entirely unrelated, MARS does sometimes produce this exact behavior of something running quickly in SSMS but horribly slow (seconds become several minutes) via EF.
One way to test this is to turn off Lazy Loading and either remove MultipleActiveResultSets=True; (the default is "false") or at least change it to be MultipleActiveResultSets=False;.
As far as I know, there is unfortunately no work-around or fix (currently) for this behavior.
Here is an instance of this issue: Same query with the same query plan takes ~10x longer when executed from ADO.NET vs. SMSS
There is an excellent article about Entity Framework performance consideration here.
I would like to draw your attention to the section on Cold vs. Warm Query Execution:
The very first time any query is made against a given model, the
Entity Framework does a lot of work behind the scenes to load and
validate the model. We frequently refer to this first query as a
"cold" query. Further queries against an already loaded model are
known as "warm" queries, and are much faster.
During LINQ query execution, the step "Metadata loading" has a high impact on performance for Cold query execution. However, once loaded metadata will be cached and future queries will run much faster. The metadata are cached outside of the DbContext and will be re-usable as long as the application pool lives.
In order to improve performance, consider the following actions:
use pre-generated views
use query plan caching
use no tracking queries (only if accessing for read-only)
create a native image of Entity Framework (only relevant if using EF 6 or later)
All those points are well documented in the link provided above. In addition, you can find additional information about creating a native image of Entity Framework here.
I don't have an specific answer as to WHY this is happening, but it certainly looks to be related with how the query is handled more than the query itself. If you say that you don't have any issues running the same generated query from SSMS, then it isn't the problem.
A workaround you can try: A stored procedure. EF can handle them very well, and it is the ideal way to deal with potentially complicated or expensive queries.
Realizing you are using Entity Framework 4.1, I would suggest you upgrade to Entity Framework 6.
There has been a lot of performance improvement and EF 6 is much faster than EF 4.1.
The MSDN article about Entity Framework performance consideration mentioned in my other response has also a comparison between EF 4.1 and EF 6.
There might be a bit of refactoring needed as a result, but the improvement in performance should be worth it (and that would reduce the technical debt at the same time).

Entity Framework Code-First too slow at startup

I know this has been asked a lot before, but I still haven't found a working fix.
I'm creating a desktop application which will regularly be started and stopped. The database is a MySQL database stored online and I'm using the newest version of EF and the MySQL connector.
I'm also working code-first. For now, I only have 3 small entities, but these will grow a lot in time. The database is generated already at startup, so nothing needs to be created anymore.
Every time the application is started (even when deployed), retreiving the first data from the database (only like 50 records, but I've also tried only 10 and it doesn't make any difference) is slow: around 5 seconds. After that, the next queries are pretty fast (around 1 second).
I've already tried generating views, but it doesn't change anything. I also create only 1 DbContext.
If I attempt to use ADO.NET, I get the results almost instantly, even on the first query (retreiving all 50 records), so it has nothing to do with a connection issue.
I'm not sure what information I have to give in order for you to help me, so feel free to ask more info.
Any idea what I could try? Is it really supposed to take like 5 seconds before the user can start working with the program?
On EF the first a query is run it has to be compiled even though the program is already complied.
I would suggest reading this http://www.codeproject.com/Articles/38174/How-to-improve-your-LINQ-query-performance-by-X and this https://msdn.microsoft.com/en-us/library/vstudio/bb896297%28v=vs.100%29.aspx and trying again to see if this helps.
Good luck!

IQueryable Count method takes longer to execute

With a WCF built on top of a DB containing around 200 tables and Entity Framework, it takes lot of time (around 2 mins) to perform login the first time after building the WCF.
Stepping into the code revealed the IQueryable.Count method to be the culprit.
This happens only the first time after building the WCF code. Consecutive execution of the Count method is fast as expected.
What could be the reason? Is entities doing some kind of a background caching of sort after rebuilding the code?
Please share your thoughts!
UPDATED:
#Craig: Thanks for the Pre-Generation of views link
Also, this link has lot of performance improvement suggestions for EF
Also, check out Lazy Loading for EF library.
This is a known problem that will be resolved with .NET 4.0.
When you first run a web based application, the code must be cached. From then on, it runs at full speed. The article shows current methods of avoiding this initial slowdown by pre-running the code before your first user hits the service.
The Lame Duck's answer is helpful (up-voted), but it does not tell the full story. The first time you execute an Entity Framework query, several things happen. One is view generation, where SQL is compiled for common queries, like loading entity sets and loading individual entities. But view generation can also be done at compile time, which saves the first, unlucky, person to run a query the performance overhead of this step. This step is repeated whenever a new ObjectContext is initialized, so the small overhead of doing view generation at compile time pays off in a big way at runtime. The second is compilation of an IQueryable into a canonical command tree, which can be optimized with CompiledQuery. You may be facing one or both of these issues, so before you write this off as a .NET 3.5 SP 1 problem, it is worth checking them out.

Categories

Resources