内连接与哪里
性能(在oracle中)有差异吗?
Select * from Table1 T1 Inner Join Table2 T2 On T1.ID = T2.ID
和
Select * from Table1 T1, Table2 T2 Where T1.ID = T2.ID
?
没有! 同样的执行计划,看看这两个表:
CREATE TABLE table1 ( id INT, name VARCHAR(20) ); CREATE TABLE table2 ( id INT, name VARCHAR(20) );
使用内部联接的查询的执行计划:
-- 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
以及使用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
如果查询优化器正在做它的工作,这些查询应该没有区别。 他们只是两种方式来指定相同的预期结果。
他们应该完全一样。 但是,作为一种编码习惯,我宁愿看到join。 它清楚地expression了你的意图,
使用JOIN
使代码更容易阅读,因为它是不言自明的。
速度没有什么区别( 我刚刚testing过 ),执行计划是一样的。
我不了解Oracle,但我知道旧的语法在SQL Server中被弃用,并最终消失。 在使用新的查询语句之前,我会先检查Oracle计划如何处理这个问题。
我更喜欢使用更新的语法,而不是将条件与其他条件混合。 在更新的语法中,创build连接的内容以及正在应用的其他条件更加清晰。 在这样一个简短的查询中不是一个大问题,但是当你有一个更复杂的查询时会变得更加混乱。 由于人们学习基本查询,所以我倾向于更喜欢人们在复杂的查询中学习使用连接语法。
而且我不是特别了解Oracle,但是我知道即使在SQL Server 2000中旧式左连接的SQL Server版本也存在缺陷,并且给出了不一致的结果(有时左连接有时是交叉连接),所以它绝不应该是用过的。 希望Oracle不会遇到同样的问题,但是左右连接在旧的语法中很难正确expression。
另外,这也是我的经验(当然这个严格的个人观点,你可能有不同的经验),那些使用ANSII标准的开发者往往会更好地理解一个连接是什么以及它在获取数据出数据库。 我相信这是因为大多数具有良好数据库理解能力的人倾向于写更复杂的查询,对我来说,使用ANSII标准比旧式更容易维护。
它们在逻辑上是相同的,但是在采用ANSI语法的早期版本的Oracle中,在更复杂的情况下经常会出现错误,所以在使用Oracle时,您有时会遇到阻碍。
[为了奖励点…]
使用JOIN语法,您可以更轻松地将连接注释为全部包含在一行中。 如果您正在debugging复杂的查询,这可能很有用
正如其他人所说,他们在function上是一样的,但JOIN更清楚地expression意图。 因此,在某些情况下(我不知道它是否会),它可以帮助查询优化器在当前的Oracle版本中,它可以帮助Oracle的未来版本中的查询优化器(没有人有任何想法),或者可以帮助你改变数据库供应商。
性能应该是相同的,但我会build议使用连接版本,因为提高外部连接的清晰度。
也可以避免使用连接版本无意的笛卡尔产品。
第三个效果是用简单的WHERE条件更容易读取SQL。
不要忘记,在Oracle中,如果连接键属性在两个表中都是相同的,那么也可以这样写:
select * from Table1 inner join Table2 using (ID);
当然,这也有相同的查询计划。
在PostgreSQL中,确实没有区别 – 它们都等同于相同的查询计划。 我99%肯定这也是甲骨文的情况。
在表格处于第三范式的情况下,表格之间的连接不应改变。 即join客户和付款应始终保持不变。
但是,我们必须从filter中区分连接 。 联结是关于关系,filter是关于分割一个整体。
SQL-92语法鼓励我们分离这两个概念,并且它比旧的语法更优先,将WHERE子句中的两个连接和filter放在一起,这是比较麻烦的。
在function上,他们是一样的说过。 我同意,虽然这样做join是更好地描述你想要做什么。 有很多次我以为我知道我是如何查询某些东西的,直到我开始进行连接,并意识到我想做一个与原来的不同的查询。
它们都是内部连接,可以做同样的事情,只需要使用更新的ANSI语法。
诚然,在function上,两个查询都应该以相同的方式处理。 但是,经验表明,如果您从使用新连接语法的视图中进行select,则使用它的结构化查询也很重要。 如果一个视图使用“join”语句,Oracle的优化器可能会感到困惑,但访问视图的查询使用传统的“where”子句join方法。
虽然两个查询的身份似乎很明显有时会发生一些奇怪的事情。 我已经来accros查询具有不同的执行计划时,将联接谓词从JOIN移动到Oracle 10g中的WHERE(对于WHERE计划更好),但我不能在简化的表和数据中重现此问题。 我认为这取决于我的数据和统计数据。 优化器是相当复杂的模块,有时它的performance神奇。
这就是为什么我们不能一般回答这个问题,因为它依赖于DB内部。 但是我们应该知道答案必须是“ 没有区别 ”。
我今天遇到这个难题时,检查我们的sp的生产超时之一,改变了从一个xml饲料build立一个表的内部连接到一个“where”子句,而不是…平均执行时间现在80毫秒超过1000执行,而在平均执行时间为2.2秒之前…执行计划的主要区别是关键查找的缺失…直到您使用这两种方法进行testing之前,您所不知道的消息。
干杯。
他们都是联合的,在哪里做同样的事情。
看看在MySQL查询中,为什么使用连接而不是在哪里?
正如kiewik所说,执行计划是一样的。
JOIN语句只是更容易阅读,更容易忘记ON条件并获得笛卡尔积。 在使用多个连接types的长查询中,这些错误可能很难检测到:SELECT * FROM t1,t2 WHERE t1.id = t2.some_field。
如果你忘记了只有一个连接条件,你会得到很长的时间来执行查询返回太多的logging…真的太多了。 有些人使用DISTINCT来修补查询,但执行起来还是很长的。
这正是为什么使用JOIN语句确实是最佳实践:更好的可维护性和更好的可读性。
此外,如果我记得,JOIN是关于内存使用优化。