Is there any difference between putting additional predicates on a JOIN statement vs. adding them as additional clauses in the WHERE statement?
Example 1: Predicate on the WHERE clause
select emp.*
from Employee emp
left join Order o on emp.Id = o.EmployeeId
where o.Cancelled = 0
Example 2: Predicate on the JOIN statement
select emp.*
from Employee emp
left join Order o on emp.Id = o.EmployeeId and o.Cancelled = 0
I ran some tests and the results show that it is actually very close, but the WHERE clause is actually slightly faster! =) I absolutely agree that it makes more sense to apply the filter on the WHERE clause, I was just curious as to the performance implications.
“Is there a performance difference between putting the JOIN conditions in the ON clause or the WHERE clause in MySQL?” No, there's no difference. The following queries are algebraically equivalent inside MySQL and will have the same execution plan.
One difference is that the first option hides the intent by expressing the join condition in the where clause. The second option, where the join condition is written out is more clear for the user reading the query. It shows the exact intent of the query.
To use the WHERE clause to perform the same join as you perform using the INNER JOIN syntax, enter both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas. This query returns the same output as the previous example.
With the first statement the outer join is effectively turned into an inner join because of the WHERE condition as it will filter out all rows from the employee table where no order was found (because o.Cancelled will be NULL then)
So the two statements don't do the same thing.
I already got the answers from some of my colleagues, but in case they don't post it here, I'll add an answer myself.
Both of these examples assume that the predicate is comparing a column on the "right" table with a scalar value.
Performance
It seems that if the predicate is on the JOIN
, then the "right" table is filtered in advance. If the predicate is part of the WHERE
clause, then all results come back and are filtered once at the end before returning the resultset.
Data Returned
if the predicate is part of the WHERE
clause, then in the situation where the "right" value is null (i.e. there is no joining row) then the entire row will not be returned in the final resultset, because the predicate will compare the value with null
and therefore return false.
Just to address the case that the additional predicate is on a column from the left hand table this can still make a difference as shown below.
WITH T1(N) AS
(
SELECT 1 UNION ALL
SELECT 2
), T2(N) AS
(
SELECT 1 UNION ALL
SELECT 2
)
SELECT T1.N, T2.N, 'ON' AS Clause
FROM T1
LEFT JOIN T2 ON T1.N = T2.N AND T1.N=1
UNION ALL
SELECT T1.N, T2.N, 'WHERE' AS Clause
FROM T1
LEFT JOIN T2 ON T1.N = T2.N
WHERE T1.N=1
Returns
N N Clause
----------- ----------- ------
1 1 ON
2 NULL ON
1 1 WHERE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With