内连接vs其中

jua*_*uan 251 sql oracle performance

是否存在性能差异(在oracle中)

Select * from Table1 T1 
Inner Join Table2 T2 On T1.ID = T2.ID
Run Code Online (Sandbox Code Playgroud)

Select * from Table1 T1, Table2 T2 
Where T1.ID = T2.ID
Run Code Online (Sandbox Code Playgroud)

kie*_*wic 190

没有!相同的执行计划,看看这两个表:

CREATE TABLE table1 (
  id INT,
  name VARCHAR(20)
);

CREATE TABLE table2 (
  id INT,
  name VARCHAR(20)
);
Run Code Online (Sandbox Code Playgroud)

使用内部联接的查询的执行计划:

-- with inner join

EXPLAIN PLAN FOR
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2
Run Code Online (Sandbox Code Playgroud)

以及使用WHERE子句的查询的执行计划.

-- with where clause

EXPLAIN PLAN FOR
SELECT * FROM table1 t1, table2 t2
WHERE t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2
Run Code Online (Sandbox Code Playgroud)

  • 我真的希望看看Oracle是否有任何官方文档说明这一点 (4认同)

Cra*_*der 67

如果查询优化器正在执行其工作,那么这些查询之间应该没有区别.它们只是两种指定相同结果的方法.

  • 我发现WHERE语法比INNER JION更容易阅读 - 我猜它就像Vegemite.世界上大多数人可能觉得它很恶心,但是孩子们喜欢吃它喜欢它. (24认同)
  • 是的,表现应该是一样的.但SELECT*FROM Table1,Table2 WHERE ...语法是EVIL! (22认同)
  • Vegemite确实令人讨厌,但我又喜欢刮胡子.去搞清楚. (3认同)
  • 我发现理解FOR INNER JOINS要比SQL-92语法容易得多.你的旅费可能会改变. (2认同)
  • @Darryl我认为,`JOIN`更易于阅读,因为联接表的条件是在此处立即定义的,而不是在“ WHERE`子句中的”某处“。我更喜欢保留“ WHERE”子句以限制数据集(例如“ WHERE DATE>(SYSDATE-1)”),而不是同时定义表之间的关系(例如“ WHERE T1.ID = T2.ID”) 。对于像所讨论的示例这样的小表来说,差别不大,但是对于涉及多个表和多个条件的大型查询,我认为它使查询更容易理解。 (2认同)

Nes*_*cio 60

它们应该完全一样.但是,作为编码实践,我宁愿看到加入.它清楚地表达了你的意图,

  • 确实.连接表示两组数据之间的语义关系,但是其中建议使用过滤集.+1 (12认同)
  • 我同意.特别是如果你要加入多个表,如果你正在进行显式连接,那么解析select语句要容易得多. (8认同)

小智 26

使用JOIN使代码更容易阅读,因为它是不言自明的.

速度没有区别(我刚测试过),执行计划是一样的.


HLG*_*GEM 15

我不知道Oracle,但我知道旧语法在SQL Server中已被弃用,并最终会消失.在我在新查询中使用旧语法之前,我会检查Oracle计划用它做什么.

我更喜欢新的语法,而不是将连接标准与其他条件混合.在更新的语法中,更清楚的是创建连接以及正在应用的其他条件.在像这样的简短查询中并不是一个大问题,但是当你有一个更复杂的查询时,它会变得更加混乱.由于人们在基本查询上学习,我倾向于更喜欢人们在复杂查询中需要之前学习使用连接语法.

我再也不知道Oracle,但我知道旧版左连接的SQL Server版本即使在SQL Server 2000中也存在缺陷,并且会产生不一致的结果(有时候左边的连接有时会是交叉连接),所以它永远不应该是用过的.希望Oracle不会遇到同样的问题,但肯定左右连接可能更难以在旧语法中正确表达.

此外,我的经验(当然这完全是个人观点,您可能有不同的经验)使用ANSII标准加入的开发人员倾向于更好地了解联接是什么以及它在获取方面意味着什么数据库中的数据.我相信这是因为大多数具有良好数据库理解力的人倾向于编写更复杂的查询,而在我看来,使用ANSII标准比使用旧样式更容易维护.


Chr*_*ill 14

[获得奖励...]

使用JOIN语法可以更轻松地注释掉连接,因为它全部包含在一行中.如果要调试复杂查询,这可能很有用

正如其他人所说,它们在功能上是相同的,但是JOIN更清楚地表达了意图.因此,它可能在某些情况下帮助查询优化器在当前的oracle版本中(我不知道它是否确实如此),它可能有助于Oracle未来版本中的查询优化器(没有人有任何想法),或者它可能有帮助,如果你改变数据库供应商.

  • 或者......轻松将INNER JOINS更改为LEFT JOINS,这样您就可以看到哪个连接导致您错过预期的行.我这样做是因为我立刻做了整个查询.如果你注释掉INNER JOINS,你就必须做一个消除过程.需要更长的时间.但是给你+1,因为除了可读性之外,这是我最喜欢INNER JOINS的原因之一! (2认同)

Dav*_*dge 13

它们在逻辑上是相同的,但在采用ANSI语法的早期版本的Oracle中,在更复杂的情况下经常出现错误,因此在使用它时有时会遇到Oracle开发人员的阻力.


小智 7

性能应该是相同的,但我建议使用join-version,因为在外连接方面提高了清晰度.

使用join-version也可以避免无意识的笛卡尔积.

第三个效果是使用更简单的WHERE条件更容易读取SQL.


che*_*rdo 6

不要忘记在Oracle中,如果两个表中的连接键属性命名相同,您也可以将其写为:

select *
from Table1 inner join Table2 using (ID);
Run Code Online (Sandbox Code Playgroud)

当然,这也有相同的查询计划.


abr*_*taf 5

在表为第三范式的情况下,表之间的连接不应更改。即加入客户和付款应始终保持不变。

但是,我们应该区分连接过滤器。联接是关于关系的,而过滤器是关于分割整体。

一些作者,参考标准(即 Jim Melton;Alan R. Simon (1993)。Understanding The New SQL: A Complete Guide. Morgan Kaufmann. pp. 11–12. ISBN 978-1-55860-245-8.) ,写了在 FROM 子句中对逗号分隔表采用 JOIN 语法的好处。

我完全同意这个观点。

有多种编写 SQL 并获得相同结果的方法,但对于许多进行团队合作的人来说,源代码易读性是一个重要方面,当然,将表与特定过滤器的相互关联方式分开是澄清源意义的一大飞跃代码。