Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework is slow because of derived tables

I am using MySQL Connector/Net 6.5.4 with LINQ to entities, and I frequently get terrible query performance because the entity framework generates queries that use derived tables.

Here is a simplified example of what I've encountered several times. In C#, I write a query like this:

var culverCustomers = from cs in db.CustomerSummaries where cs.Street == "Culver" select cs;
// later...
var sortedCustomers = culverCustomers.OrderBy(cs => cs.Name).ToList();

Instead of generating simple a query like this:

SELECT cust.id FROM customer_summary cust WHERE cust.street = "Culver" ORDER BY cust.name

The entity framework generates a query with a derived table like this:

SELECT Project1.id FROM (
    SELECT cust.id, cust.name, cust.street FROM customer_summary cust
    WHERE Project1.street = "Culver"
) AS Project1 -- here is where the EF generates a pointless derived table
ORDER BY Project1.name

If I explain both queries I get this for the first query:

id, select_type, table, type, possible_keys, rows
1,  PRIMARY,     addr,  ALL,  PRIMARY,       9
1,  PRIMARY,     cust,  ref,  PRIMARY,       4

... and something awful like this for the entity framework query

id, select_type, table,      type, possible_keys, rows
1,  PRIMARY,     <derived2>, ALL,                 9639
2,  DERIVED,     addr,       ALL,  PRIMARY,       9
2,  DERIVED,     cust,       ref,  PRIMARY,       4

Note the first row, where MySQL explains that it's scanning 9000+ records. Because of the derived table, MySQL is creating a temp table and loading every row. (Or so I'm deducing based on articles like this one: Derived Tables and Views Performance)

How can I prevent the Entity Framework from using a derived table, or how can I convince MySQL to do the obvious optimization for queries like this?

For completion, here is the view that is the source for this linq query:

create view  customer_summary as
select cust.id, cust.name, addr.street
customers cust 
join addresses addr
on addr.customer_id = cust.id
like image 991
ThisIsTheDave Avatar asked Nov 02 '12 18:11

ThisIsTheDave


People also ask

Is entity framework good for large database?

There are plenty of ways to improve performace of entity framrework with large dataset. It will resolve you major pain area and the section where you cannot see the performance improvement use classic DB stored procedure and call them with entity framework.

Why Dapper is faster than Entity Framework?

Dapper vs Entity Framework Core Dapper is literally much faster than Entity Framework Core considering the fact that there are no bells and whistles in Dapper. It is a straight forward Micro ORM that has minimal features as well.

Does Entity Framework cache data?

Entity Framework has the following forms of caching built-in: Object caching – the ObjectStateManager built into an ObjectContext instance keeps track in memory of the objects that have been retrieved using that instance. This is also known as first-level cache.


1 Answers

I think your query statement is missing 'select'. You have not identified the record(s) you want. your query:

var culverCustomers = from cs in db.CustomerSummaries 
                        where cs.Street == "Culver";

//no select

what are you selecting from the table? try this

example:

var culverCustomers =  from cs in db.CustomerSummaries 
                        where cs.Street == "Culver"
                        select cs;
like image 84
user3676608 Avatar answered Nov 03 '22 04:11

user3676608