两者之间的性能(在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
?
inner join ... on
在where
子句中将相等的连接条件与放置相等的连接条件之间会有怎样不同的结果。
join
两者之间的性能(在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
?
inner join ... on
在where
子句中将相等的连接条件与放置相等的连接条件之间会有怎样不同的结果。
join
Answers:
没有!相同的执行计划,请看下面两个表:
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
s更容易阅读,因为连接表的条件是在此处立即定义的,而不是在WHERE
子句中的“某处” 。我更喜欢保留WHERE
用于限制数据集的子句(例如WHERE DATE > (SYSDATE - 1)
),而不是也定义表之间的关系(例如WHERE T1.ID = T2.ID
)。对于像所讨论的示例这样的小表来说,差别不大,但是对于涉及多个表和多个条件的大型查询,我认为这使查询更容易理解。
我不了解Oracle,但我知道SQL Server中不赞成使用旧语法,并且最终将消失。在新查询中使用旧语法之前,我将检查Oracle计划如何使用它。
我更喜欢较新的语法,而不是将合并条件与其他需要的条件混合使用。在较新的语法中,更清楚地说明了创建连接的条件以及正在应用的其他条件。在像这样的短查询中,这并不是一个大问题,但是当您拥有更复杂的查询时,它会变得更加混乱。由于人们是在基本查询中学习的,因此我倾向于偏向于人们在复杂查询中需要使用联接语法之前就学习使用联接语法。
再说一次,我不特别了解Oracle,但我知道即使在SQL Server 2000中,旧样式的左连接的SQL Server版本也存在缺陷,并且结果不一致(有时左连接有时是交叉连接),因此永远不应用过的。希望Oracle不会遇到相同的问题,但是可以肯定的是,用旧语法正确表达左右联接可能会更加困难。
另外,根据我的经验(当然,这完全是个人观点,您可能会有不同的经验),使用ANSI I标准联接的开发人员倾向于更好地了解联接的含义以及获得联接的含义。数据从数据库中移出。我相信这是因为大多数具有良好数据库理解的人都倾向于编写更复杂的查询,而在我看来,使用ANSI I标准要比使用旧样式维护起来容易得多。
[加分...]
使用JOIN语法使您可以更轻松地注释掉联接,因为联接全部包含在一行中。如果您要调试复杂的查询,这可能会很有用
就像其他人说的那样,它们在功能上是相同的,但是JOIN更清楚地表明了意图。因此,它可能会在某些情况下在当前oracle版本中帮助查询优化器(我不知道是否这样做),它可能会在Oracle的未来版本中帮助查询优化器(没人知道),或者在以下情况下可能会有所帮助您更改数据库供应商。
它们在逻辑上是相同的,但是在采用ANSI语法的Oracle的早期版本中,在更复杂的情况下常常会出现bug,因此在使用它时有时会遇到来自Oracle开发人员的阻力。
在表为第三范式的情况下,表之间的联接不应更改。即加入客户和付款应始终保持不变。
但是,我们应该区分join和filter。联接是关于关系的,而过滤器是关于整体的。
一些作者提到了该标准(例如Jim Melton; Alan R. Simon(1993)。《理解新SQL:完整指南》,Morgan Kaufmann。第11–12页。ISBN 978-1-55860-245-8。) ,他在FROM子句中描述了在逗号分隔的表上采用JOIN语法的好处。
我完全同意这一观点。
有多种方法可以编写SQL并获得相同的结果,但是对于许多团队合作人员而言,源代码的可读性是一个重要方面,并且在明确源代码的意义上,将表之间的相互关系与特定的过滤器分开无疑是一个巨大的飞跃。码。
尽管两个查询的身份似乎很明显,但有时还是会发生一些奇怪的事情。我已经注意到,在Oracle 10g中将联接谓词从JOIN移到WHERE时,查询具有不同的执行计划(因为WHERE计划更好),但是我无法在简化的表和数据中重现此问题。我认为这取决于我的数据和统计数据。优化器是一个非常复杂的模块,有时表现得很神奇。
这就是为什么我们通常不能回答这个问题的原因,因为它取决于数据库内部。但是我们应该知道答案必须是“ 无差异 ”。
我今天在检查我们sp的生产中的超时时遇到了这个难题,将xml feed构建的表的内部联接从xml feed更改为'where'子句....现在,平均执行时间是1000次执行中的80ms,而在平均执行时间为2.2秒之前...执行计划的主要区别在于键查找的缺失...在使用这两种方法进行测试之前,您不会知道该消息。
干杯。
它们都是联接,并且在相同的地方执行。