I have a common database joining situation involving three tables. One table, A, is the main table with a primary key named id
. Tables B and C contain auxiliary data for entries and A, and each also has a column named id
which is a foreign key pointing to A.id
. Now, if I want all data from A, B and C in one query, I would write:
SELECT *
FROM A
INNER JOIN B
ON B.id = A.id
INNER JOIN C
ON C.id = A.id
which of course works perfectly.
Recently, our DBA told us that this is inefficient in Oracle, and you need to join conditions between C and B as well, as follows:
SELECT *
FROM A
INNER JOIN B
ON B.id = A.id
INNER JOIN C
ON C.id = A.id AND C.id = B.id
This looked redundant to me, so naturally I didn't believe here. Until I actually ran into a slow query that had a terrible execution plan, and managed to fix it by exactly adding the missing join condition. I ran explain plan on both versions: the one without the "redundant" query condition had a cost of 1 035 while the "improved" one had 389 (and there were huge differences in cardinality and bytes as well). Both queries produced the exact same result.
Can anyone explain why this extra condition makes a difference? To me C and B are not even related. Note also that if you take away the other join condition it is equally bad - they both need to be there.