Reputation: 11375
Preamble
As of late, I see too many geeks commenting on Oracle questions saying "Do not use (+) operator, rather use JOIN syntax".
Question
I do see that both work well. But what is the real difference between using them? I would welcome answers more from experience.
I did read something on Oracle documentation but it’s not good enough to make me understand or feel comfortable with the comprehensive information.
Note: I am planning to migrate 200+ packages and procedures, if the Keyword should be used instead of (+)
Posting samples
┌───────────────────────────────────┬─────────────────────────────────────────────┐
│ INNER JOIN - CONVENTIONAL │ INNER JOIN - ANSI SYNTAX │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT │ SELECT │
│ emp.deptno │ ename, │
│ FROM │ dname, │
│ emp, │ emp.deptno, │
│ dept │ dept.deptno │
│ WHERE │ FROM │
│ emp.deptno = dept.deptno; │ scott.emp INNER JOIN scott.dept │
│ │ ON emp.deptno = dept.deptno; │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ LEFT OUTER JOIN - CONVENTIONAL │ LEFT OUTER JOIN - ANSI SYNTAX │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT │ SELECT │
│ emp.deptno │ ename, │
│ FROM │ dname, │
│ emp, │ emp.deptno, │
│ dept │ dept.deptno │
│ WHERE │ FROM │
│ emp.deptno = dept.deptno(+); │ scott.emp LEFT OUTER JOIN scott.dept │
│ │ ON emp.deptno = dept.deptno; │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ RIGHT OUTER JOIN - CONVENTIONAL │ RIGHT OUTER JOIN - ANSI SYNTAX │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT │ SELECT │
│ emp.deptno │ ename, │
│ FROM │ dname, │
│ emp, │ emp.deptno, │
│ dept │ dept.deptno │
│ WHERE │ FROM │
│ emp.deptno(+) = dept.deptno; │ scott.emp RIGHT OUTER JOIN scott.dept │
│ │ ON emp.deptno = dept.deptno; │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ FULL OUTER JOIN - CONVENTIONAL │ FULL OUTER JOIN - ANSI SYNTAX │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT │ SELECT │
│ * │ * │
│ FROM │ FROM │
│ emp, │ scott.emp FULL OUTER JOIN scott.dept │
│ dept │ ON emp.deptno = dept.deptno; │
│ WHERE │ │
│ emp.deptno = dept.deptno(+) │ │
│ UNION ALL │ │
│ SELECT │ │
│ * │ │
│ FROM │ │
│ emp, │ │
│ dept │ │
│ WHERE │ │
│ emp.deptno(+) = dept.deptno │ │
│ AND emp.deptno IS NULL; │ │
└───────────────────────────────────┴─────────────────────────────────────────────┘
PS: Read the summary of answers for all updates grouped.
Upvotes: 35
Views: 62410
Reputation: 11
I was advocate of ANSI joins till last week. Till realised weird behaviour at one of my selects. After digging up Oracle bug base I learned Oracle isn't supporting ANSI joins natively - ANSI joins are being translated to (+) notation and then processed. And this translation has some unacceptable bugs. Unacceptable both because our client isn't applying patches and because some new bugs were introduced even at 12c version - very simple test case with three tables, one record and two outer joins. Seems like guys are not doing automated regression testing at all
Upvotes: 1
Reputation:
As a practice, you should always use ANSI syntax. Better don't rework on packages and procedures. Rather you can fix things when you do any maintenance on those scripts individually. There will not be any difference in plans due to syntax.
Quest SQL optimizer rewrites with all possible combinations to find a better plan. So you still need to search one SQL from its 100+ results.
Upvotes: 5
Reputation: 525
Talking from experience in work, using the JOIN
rather than (+)
is more simple,faster, better looking and better to work with solution ,specially when you work with multi database selects (throughout synonyms), with a lot of tables in it (ex.: 40+ tables) in big database (1000+ tables,some tables with more than 2 billion rows),you will feel big difference.
Upvotes: 3
Reputation: 11375
Grouping answers together
Possible Pitfall in using ANSI syntax on 12c engine
Including a possibility of bug in JOIN in 12c. See here
FOLLOW UP:
Quest SQL optimizer tool
rewrites the SQL to ANSI syntax.
Upvotes: 12
Reputation: 3499
If your 200+ packages work as intended with "old fashioned" syntax, let it be.
SQL will not start to perform better after migration to ANSI syntax - it's just different syntax.
All that being said, ANSI syntax is cleaner - you are not going to normal join if you forget (+) in some multi-column outer join.
In the past there were some bugs with ANSI syntax but if you go with latest 11.2 or 12.1 that should be fixed already.
Of course, you know your environment and priorities better - as SchmitzIT said - ANSI syntax is part of SQL standard and it would help when going to use some other RDBMS product.
Upvotes: 29
Reputation: 511
Some commenteers have said that (+) syntax doesn't allow for full outer joins. It does, so this is not the issue: (LEFT OUTER JOIN) UNION ALL (RIGHT OUTER JOIN).
Others have said that performance is the reason to make the switch. That's a bunch of BS, especially in SQL. Of course, there are some guidelines, but every query and every database has its own peculiarities, you have to tune for specific not for general situations.
The reasons to switch from (+), beside not being standard, are its limitations as opposed to the new explicit syntax: http://docs.oracle.com/cd/E16655_01/server.121/e17209/queries006.htm#SQLRF52354. Start reading from here: "Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator."
Upvotes: 3
Reputation: 5072
The (+) sign used in Outer joins is the Oracle syntax for Outer joins
From the information gathered from reliable oracle sources i could see that you can keep the Oracle outer join syntax(+) for existing packages since there are 200+ packages and since internally Oracle still converts them from ANSI syntax to Oracle syntax.
Kindly make use of the ANSI syntax in future where there in limitations for using(+) operator
Please find the links for detailed explanation on (+) sign Outer joins which might help you decide on your migration
Oracle Outer Join syntax and ANSI syntax
Limitations of using (+) Outer joins
More information about Oracle outer join
(+) Outer join Operator recommended in Java when using Oracle JDBC drivers
Upvotes: 3
Reputation: 8932
Separating your query into join conditions and where conditions can give the optimizer an additional hint. Join conditions have a very low selectivity on each table and a high selectivity on the tuples in the theoretical cross product. Conditions in the where statement usually have a much higher selectivity.
In a join condition for each row on the left there is very likely a value on the right (and vice versa). So such conditions are good to join results from two tables, but they doe not help very much in eliminating values from each individual table from the result set.
Conditions in the where clause can usually be used to eliminate individual rows from one table from the result set.
So is is a good strategy to run first the where conditions on the individual tables and eliminate as much rows as possible from the result set. After that one can use the join conditions to combine the surviving rows.
It's not clear if the Oracle optimizer really uses the position of the condition in the SQL statement as a hint for optimizing the query. I guess it is more interested in the hard facts in the table statistics (there was some change in how Oracle handles different joins in 11g R1, see this post from the Oracle optimizer team for more details).
At least for me as a human it is very helpful to know if a statement has selectivity on a singe table when I try to understand and optimize a query. You should also consider this, when you want to put multiple condition in a ON clause (e.g. ON (a.x=b.x AND a.y=b.y
) vs. putting one of the conditions in the where clasue: Just check, how selective the condition is.
For existing queries keep the syntax as is. When creating a new query or refactor an existing one, try yo sort the predicates on selectivity using the "JOIN ON" syntax: If it is not very selectable on a single table put it in the ON part, otherwise in the WHERE part.
Upvotes: 3
Reputation: 4342
I used both approaches on different projects and I prefer JOIN
syntax.
ON
clause and filter
conditions in WHERE
clause. Upvotes: 2
Reputation: 9602
Apart from the reasons mentioned by others, using the JOIN operators ensure your SQL code is ANSI compliant, and thus would allow a front-end application to be more easily ported for other database platforms.
Upvotes: 6
Reputation: 52386
In 11g you should be using ANSI join syntax. It is more flexible (support for full outer joins and partitioned joins), and as the documentation states:
Oracle strongly recommends that you use the more flexible FROM clause join syntax shown in the former example.
That's reason enough.
Upvotes: 15