Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq, is select().SingleorDefault() a bad idea?

Tags:

c#

asp.net

linq

 var queueitem = context.CrawlerQueues.
                 Select(cq => new{cq.Guid,cq.Result}).
                 SingleOrDefault(cq => cq.Guid == guid);

Is above a bad idea, will it first select all database rows and then find the one or will it be smart and see the context its used within and only fetch the one row.

Reason for doing this is i want to return only the Guid and the Result coloums.

return Newtonsoft.Json.JsonConvert.SerializeObject(queueitem, Formatting.Indented);

How would i find the answer to this without having to monitor network flow or the requests made to the database?

like image 203
Poul K. Sørensen Avatar asked Jan 31 '12 05:01

Poul K. Sørensen


1 Answers

"will it first select all database rows and then find the one "

Technically, no, the combination of .Select followed by .SingleOrDefault will not do that. Select() sets up the parameters for the query, but it doesn't actually fetch any data. LINQ's deferred execution doesn't fetch any rows until something actually has to produce a data result. You can compose multiple queries together (.Select(...).Select(..) etc) and nothing actually fetches any rows until you perform an operation that returns data, such as First() or .ToList().

However, the use of Single() may result in scanning the entire dataset to prove that the one matching row is the only matching row.

Think about it: how will the query know that the one row is the only row in the dataset that matches? It will have to try to find the next row. If there really is only one row that matches out of millions in the dataset, Single() may have to run through all of those millions of rows to prove the current match is the one and only match.

If your dataset is SQL, and your data is indexed in a manner that allows query optimization, then Single() might not be so bad. But if your SQL data isn't indexed in a way that's helpful to this query, Single() may create a lot of work for the SQL server.

Single() is appropriate if your program logic really needs to know that the returned row is the one and only row in the entire dataset. However, there are other ways to guarantee uniqueness. If you can set up a primary key on your data that matches your LINQ condition, then only one matching row can exist / be added to the database to begin with, so you don't really need Single(). (And ironically, Single()'s performance will be trivially fast in this case too because the primary key index can be used to optimize the query)

If you just want the first row that matches the condition, use First() instead of Single(). First() only has to scan rows of data until it finds the first match. It doesn't have to continue scanning rows to prove that the first match is the only match, like Single().

like image 134
dthorpe Avatar answered Oct 04 '22 06:10

dthorpe