Re: SQL to Linq - Left, Right and Inner Joins
- From: "Frans Bouma [C# MVP]" <perseus.usenetNOSPAM@xxxxxxxxx>
- Date: Sun, 06 Jul 2008 12:22:11 +0200
Jon Skeet [C# MVP] wrote:
Frans Bouma [C# MVP] <perseus.usenetNOSPAM@xxxxxxxxx> wrote:Michel Walsh wrote:If used alone, yes, but with a WHERE clause, MS SQL Server optimizer should recognize an (implicit) inner join and thus, limit the effective amount of data transferred through the wire.That's not what makes it inefficient. The cross-join execution path is often less ideal as the cross-join action by itself is first handled, and THEN the where clause is handled to filter out rows you don't want.
I'd certainly hope that the query optimiser would do the job there though. For instance, if the where clause is on an indexed column I'd be *hugely* surprised if the inner join were fully evaluated by SQL server before looking at the index.
In database land, 'hope' isn't a tool in your toolbox. In simple queries like:
select distinct c.* from customers c cross join orders o
where c.CustomerId = o.Customerid
vs.
select distinct c.* from customers c inner join orders o
on c.Customerid = o.CustomerId
the execution plan is the same. It could be that in database ABC this isn't the case however. It also can be that with more explicit joins and explicit where clauses, the optimizer gives up and the execution plans will differ. For example, in some queries, moving the where clause to the ON clause of a left join can increase performance. For example:
select distinct c.* from customers c inner join orders o
on c.Customerid = o.CustomerId
inner join [order details] od on
o.OrderId = od.Orderid
where c.Country='USA'
select distinct c.* from customers c inner join orders o
on c.Customerid = o.CustomerId
and c.Country='USA'
inner join [order details] od on
o.OrderId = od.Orderid
The second query has less reads than the first query. The main trick is that with more complicated joins, every next table to join with the set is joined more efficiently if the set it has to be joined with is smaller. So if you can already limit that set with the filter you'll apply anyway, it will bring down the overall query burden. With simple queries this might not be noticable, but these are fast anyway. It's the large queries which are the point of interest as these will also take the majority of the performance eaten by the application.
It's also the case that you can't mimic all queries with crossjoins + wheres. For example, some LEFT join constructs are hard or impossible to formulate with solely cross-joins and where clauses.
It's not like LINQ passes the join in one SQL statement and then applies the where clause separately: the query optimiser has the full query to work with.
That's not the point. The point is that Linq contains a set-theory operator 'join' but has just 1 argument for it and has no freedom how to formulate the predicate to use in the join of the two sets. I know linq works with sequences and not sets, but it would have been way better if 'join' in Linq would have had normal predicate support and a join argument, it wouldn't have hurt Linq in any way shape or form.
Btw, The cross joins in MS code often rely on a T-SQL specific statement 'CROSS APPLY', which isn't a known statement in many other databases.
FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
.
- Follow-Ups:
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Michel Walsh
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Jon Skeet [C# MVP]
- Re: SQL to Linq - Left, Right and Inner Joins
- References:
- SQL to Linq - Left, Right and Inner Joins
- From: shapper
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Michel Walsh
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Frans Bouma [C# MVP]
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Michel Walsh
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Frans Bouma [C# MVP]
- Re: SQL to Linq - Left, Right and Inner Joins
- From: Jon Skeet [C# MVP]
- SQL to Linq - Left, Right and Inner Joins
- Prev by Date: Re: How to pass a const object (read only object) to a method?
- Next by Date: Re: How to pass a const object (read only object) to a method?
- Previous by thread: Re: SQL to Linq - Left, Right and Inner Joins
- Next by thread: Re: SQL to Linq - Left, Right and Inner Joins
- Index(es):
Relevant Pages
|
Loading