简体   繁体   中英

INNER JOIN condition in WHERE clause or ON clause?

I mistyped a query today, but it still worked and gave the intended result. I meant to run this query:

SELECT e.id FROM employees e JOIN users u ON u.email=e.email WHERE u.id='139840'

but I accidentally ran this query

SELECT e.id FROM employees e JOIN users u ON u.email=e.email AND u.id='139840'

(note the AND instead of WHERE in the last clause)

and both returned the correct employee id from the user id.

What is the difference between these 2 queries? Does the second form only join members of the 2 tables meeting the criteria, whereas the first one would join the entire table, and then run the query? Is one more or less efficient than the other? Is it something else I am missing?

Thanks!

For inner joins like this they are logically equivalent. However, you can run in to situations where a condition in the join clause means something different than a condition in the where clause.

As a simple illustration, imagine you do a left join like so;

select x.id
from x
       left join y
         on x.id = y.id
;

Here we're taking all the rows from x, regardless of whether there is a matching id in y. Now let's say our join condition grows - we're not just looking for matches in y based on the id but also on id_type.

select x.id
from x
       left join y
         on x.id = y.id
         and y.id_type = 'some type'
;

Again this gives all the rows in x regardless of whether there is a matching (id, id_type) in y.

This is very different, though:

select x.id
from x
       left join y
         on x.id = y.id
where y.id_type = 'some type'
;

In this situation, we're picking all the rows of x and trying to match to rows from y. Now for rows for which there is no match in y, y.id_type will be null. Because of that, y.id_type = 'some type' isn't satisfied, so those rows where there is no match are discarded, which effectively turned this in to an inner join.

Long story short: for inner joins it doesn't matter where the conditions go but for outer joins it can.

The optimizer will treat them the same. You can do an EXPLAIN to prove it to yourself.

Therefore, write the one that is clearer.

SELECT e.id
FROM employees e JOIN users u ON u.email=e.email
WHERE u.id='139840'

In the case of an INNER JOIN, the two queries are semantically the same, meaning they are guaranteed to have the same results. If you were using an OUTER join, the meaning of the two queries could be very different, with different results.

Performance-wise, I would expect that these two queries would result in the same execution plan. However, the query engine might surprise you. The only way to know is to view the execution plans for the two queries.

If it were an outer join instead of inner, you'd get unintended results, but when using an inner join it makes no real difference whether you use additional join criteria instead of a WHERE clause.

Performance-wise they are most likely identical, but can't be certain.

I brought this up with my colleagues on our team at work. This response is a bit SQL Server centered and not MySQL. However, the optimizer should have similarities in operation between SQL and MySQL..

Some thoughts: Essentially, if you have to add a WHERE, there are additional table scans done to verify equality for each condition (This goes up by orders of magnitude with an AND or dataset, an OR, the decision is cast at the first true condition) – if you have one id pointer in the example given it is extremely quick conversely, if you have to find all of the records that belong to a company or department it becomes more obscure as you may have multiples of records. If you can apply the equals condition, it is far more effective when working with an AuditLog or EventLog table that has zillions of rows. One would not really see the large benefits of this on small tables (at around 200,000 rows or so).

From: Allesandro Alpi http://suxstellino.wordpress.com/2013/01/07/sql-server-logical-query-processing-summary/

From: Itzik Ben-Gan http://tsql.solidq.com/books/insidetsql2008/Logical%20Query%20Processing%20Poster.pdf

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM