Oracle Joins - 常规语法与 ANSI 语法的比较
序言
最近,我看到太多极客在评论 Oracle 问题时说不要使用 (+) 运算符,而是使用 JOIN 语法".
As of late, I see too many geeks commenting on Oracle questions saying "Do not use (+) operator, rather use JOIN syntax".
问题
我确实看到两者都运行良好.但是使用它们之间的真正区别是什么?我欢迎从经验中获得更多答案.
I do see that both work well. But what is the real difference between using them? I would welcome answers more from experience.
- 使用它们时是否与应用程序、性能等方面的限制有关?
- 你有什么建议给我?
我确实在 Oracle 文档a> 但不足以让我理解或对全面的信息感到满意.
I did read something on Oracle documentation but it’s not good enough to make me understand or feel comfortable with the comprehensive information.
注意:我计划迁移 200 多个包和程序,如果应该使用关键字而不是 (+)
Note: I am planning to migrate 200+ packages and procedures, if the Keyword should be used instead of (+)
- 还有任何免费软件工具可以进行重写吗?
发布示例
┌───────────────────────────────────┬─────────────────────────────────────────────┐
│ 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:阅读分组的所有更新的答案摘要.
PS: Read the summary of answers for all updates grouped.
推荐答案
将答案分组
- 使用显式联接而不是隐式联接(无论它们是否是外联接),因为使用隐式联接意外创建笛卡尔积要容易得多.使用显式 JOIN,您不能意外"创建一个.涉及的表越多,您错过一个连接条件的风险就越高.
- 与 ANSI 连接相比,基本上 (+) 受到严重限制.此外,它仅在 Oracle 中可用,而所有主要 DBMS 都支持 ANSI 连接语法
- 在迁移到 ANSI 语法后,SQL 不会开始表现得更好——它只是不同的语法.
- Oracle 强烈建议您使用前一个示例中显示的更灵活的 FROM 子句连接语法.过去,ANSI 语法存在一些错误,但如果您使用最新的 11.2 或 12.1,应该已经修复了.
- 使用 JOIN 运算符可确保您的 SQL 代码符合 ANSI,从而使前端应用程序可以更轻松地移植到其他数据库平台.
- 连接条件对每个表的选择性非常低,而对理论叉积中的元组具有很高的选择性.where 语句中的条件通常具有更高的选择性.
- Oracle 在内部将 ANSI 语法转换为 (+) 语法,您可以在执行计划的谓词信息部分看到这种情况.
在 12c 引擎上使用 ANSI 语法的可能陷阱
包括 12c 中 JOIN 中可能存在的错误.请参阅此处
Including a possibility of bug in JOIN in 12c. See here
跟进:
Quest SQL 优化器工具
将 SQL 重写为 ANSI 语法.
Quest SQL optimizer tool
rewrites the SQL to ANSI syntax.
相关文章