Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Entity Framework generate nested SQL queries?

Tags:

Why does the Entity Framework generate nested SQL queries?

I have this code

    var db = new Context();     var result = db.Network.Where(x => x.ServerID == serverId)         .OrderBy(x=> x.StartTime)         .Take(limit); 

Which generates this! (Note the double select statement)

SELECT `Project1`.`Id`,  `Project1`.`ServerID`,  `Project1`.`EventId`,  `Project1`.`StartTime` FROM (SELECT `Extent1`.`Id`,  `Extent1`.`ServerID`,  `Extent1`.`EventId`,  `Extent1`.`StartTime` FROM `Networkes` AS `Extent1`  WHERE `Extent1`.`ServerID` = @p__linq__0) AS `Project1`  ORDER BY  `Project1`.`StartTime` DESC LIMIT 5 

What should I change so that it results in one select statement? I'm using MySQL and Entity Framework with Code First.

Update

I have the same result regardless of the type of the parameter passed to the OrderBy() method.

Update 2: Timed

Total Time (hh:mm:ss.ms)    05:34:13.000 Average Time (hh:mm:ss.ms)  25:42.000 Max Time (hh:mm:ss.ms)  51:54.000 Count   13 First Seen  Nov 6, 12 19:48:19 Last Seen   Nov 6, 12 20:40:22 

Raw query:

SELECT `Project?`.`Id`, `Project?`.`ServerID`, `Project?`.`EventId`, `Project?`.`StartTime` FROM (SELECT `Extent?`.`Id`, `Extent?`.`ServerID`, `Extent?`.`EventId`, `Extent?`.`StartTime`, FROM `Network` AS `Extent?` WHERE `Extent?`.`ServerID` = ?) AS `Project?` ORDER BY `Project?`.`Starttime` DESC LIMIT ? 

I used a program to take snapshots from the current process in MySQL.

Other queries were executed at the same time, but when I change it to just one SELECT statement, it NEVER goes over one second. Maybe I have something else that's going on; I'm asking 'cause I'm not so into DBs...

Update 3: The explain statement

The Entity Framework generated

'1', 'PRIMARY', '<derived2>', 'ALL', NULL, NULL, NULL, NULL, '46', 'Using filesort' '2', 'DERIVED', 'Extent?', 'ref', 'serveridneventid,serverid', 'serveridneventid', '109', '', '45', 'Using where' 

One liner

'1', 'SIMPLE', 'network', 'ref', 'serveridneventid,serverid', 'serveridneventid', '109', 'const', '45', 'Using where; Using filesort' 

This is from my QA environment, so the timing I pasted above is not related to the rowcount explain statements. I think that there are about 500,000 records that match one server ID.

Solution

I switched from MySQL to SQL Server. I don't want to end up completely rewriting the application layer.

like image 807
Simon Edström Avatar asked Nov 06 '12 19:11

Simon Edström


People also ask

Why do we need nested queries?

A Subquery or Inner query or a Nested query is a query within another SQL query and embedded within the WHERE clause. A subquery is used to return data that will be used in the main query as a condition to further restrict the data to be retrieved.

Why should nested SQL queries be avoided?

Personally I prefer to avoid nested queries until they are necessary for the simple reason that nested queries can make the code less human readable and make debugging and collaboration more painful.

How does nested query work in SQL?

In nested queries, a query is written inside a query. The result of inner query is used in execution of outer query. We will use STUDENT, COURSE, STUDENT_COURSE tables for understanding nested queries.


1 Answers

It's the easiest way to build the query logically from the expression tree. Usually the performance will not be an issue. If you are having performance issues you can try something like this to get the entities back:

var results = db.ExecuteStoreQuery<Network>(     "SELECT Id, ServerID, EventId, StartTime FROM Network WHERE ServerID = @ID",      serverId);  results = results.OrderBy(x=> x.StartTime).Take(limit); 
like image 88
PeteGO Avatar answered Oct 15 '22 22:10

PeteGO