具有条件的表之间的SQL联接
我正在考虑哪种方法应该是在两个或多个表之间进行连接的最佳方法(考虑执行时间)。我有三种方法: 第一种方式:具有条件的表之间的SQL联接,sql,oracle,join,Sql,Oracle,Join,我正在考虑哪种方法应该是在两个或多个表之间进行连接的最佳方法(考虑执行时间)。我有三种方法: 第一种方式: select * from TABLE A inner join TABLE B on A.KEY = B.KEY where B.PARAM=VALUE 第二条路 select * from TABLE A inner join TABLE B on A.KEY = B.KEY and B.PARAM=VALUE 第三条路 select * from TABLE A inne
select * from
TABLE A inner join TABLE B on A.KEY = B.KEY
where
B.PARAM=VALUE
第二条路
select * from
TABLE A inner join TABLE B on A.KEY = B.KEY
and B.PARAM=VALUE
第三条路
select * from
TABLE A inner join (Select * from TABLE B where B.PARAM=VALUE) J ON A.KEY=J.KEY
假设表的行数超过100万行
你的意见是什么?如果存在,哪种方法应该是正确的?1M行实际上并没有那么多——特别是如果您有合理的索引。我会从尽可能使您的查询可读性和可维护性开始,并且只有在您注意到查询的性能问题时才开始优化(正如Gordon Linoff在他的评论中所说的,这三者之间是否会有差异,这是值得怀疑的)
这可能是一个品味的问题,但对我来说,第三种方式似乎很笨拙,所以我把它划掉。就个人而言,我更喜欢使用
JOIN
语法进行连接逻辑(即,A和B的行如何匹配)和WHERE
进行过滤(即,一旦匹配,我会对哪些行感兴趣),因此我选择第一种方法。但是,这又一次归结为个人品味和偏好。您需要查看查询的执行计划,以判断哪一个是计算效率最高的。正如在评论中指出的,你可能会发现它们是等价的。这里有一些关于的信息。根据您使用的编辑器/IDE,可能是实现此目的的快捷方式,例如PL/SQL Developer中的F5。通常将条件放入where子句或联接条件在内部联接中没有明显的差异。如果使用外部联接,则将条件放入where子句可以缩短查询时间,因为在的where子句中使用条件时 左侧外部联接,不满足条件的行将从结果集中删除,结果集将变小。 但是,如果在左外部联接的join子句中使用条件,则不会删除任何行,并且与在where子句中使用条件相比,结果集更大。 如需更多说明,请遵循以下示例 创建表A ( 无编号 阿纳姆·瓦尔查尔2(10) 日期 ) ----数据 插入 从dual中选择1,'Amand',to_date('20130101','yyyyymmdd'); 承诺 插入 从dual中选择2,'Alex',to_date('20130101','yyyymmdd'); 承诺 插入 从dual中选择3,'Angel',to_date('20130201','yyyyymmdd') 犯罪 创建表B ( bno编号 bname VARCHAR2(10) 日期 ) 插入B 从dual中选择3,'BOB',to_date('20130201','yyyyymmdd'); 承诺 插入B 从dual中选择2,'Br',to_date('20130101','yyyyymmdd'); 承诺 插入B 从dual中选择1,'Bn',to_date('20130101','yyyyymmdd'); 承诺 首先,我们有一个普通查询,它将两个表相互连接起来:
select * from a inner join b on a.ano=b.bno
结果集有3条记录。
现在请运行以下查询:
select * from a inner join b on a.ano=b.bno and a.rdate=to_date('20130101','yyyymmdd')
select * from a inner join b on a.ano=b.bno where a.rdate=to_date('20130101','yyyymmdd')
正如您看到的,上面的结果行数没有差异,根据我的经验,对于大容量的数据,没有明显的性能差异
请运行以下查询:
select * from a left outer join b on a.ano=b.bno and a.rdate=to_date('20130101','yyyymmdd')
在这种情况下,输出记录的计数将等于表A记录
select * from a left outer join b on a.ano=b.bno where a.rdate=to_date('20130101','yyyymmdd')
在本例中,不满足条件的A的记录将从结果集中删除,正如我所说的,结果集中的记录将更少(在本例中为2条记录)
根据上述例子,我们可以得出以下结论:
1-如果使用内部连接,
将条件放入where子句或join子句之间没有特殊区别,但请尝试将表放入from子句,以获得最小的中间结果行计数:
()
2-在使用外部联接的情况下,只要不关心精确的结果行计数(不关心表A中缺少的记录,因为表B中没有成对的记录,并且表B的字段对于结果集中的这些记录将为空),将该条件放入where子句中,以删除一组不符合该条件的行,并通过减少结果行数明显缩短查询时间
但在特殊情况下,必须将条件放在join部分。例如,如果希望结果行数等于表“A”行数(这种情况在ETL过程中很常见),则必须将条件放在join子句中
3-避免子查询被许多可靠的资源和专家程序员推荐。它通常会增加查询时间,并且在结果数据集很小的情况下,您可以使用子查询
我希望这将是有用的:)Oracle查询优化器将对所有这些问题一视同仁,不会有太大的性能差异。您是否检查了结果?要回答有关性能的问题,您需要查看执行计划(或在类似情况下对查询计时)。Oracle有一个很好的优化器,所以我猜这三个查询都会有相同的计划和相同的性能。当发布性能相关的问题时,最好阅读以下内容:您真的只考虑内部联接,还是只是为了保持示例的小型化?如果必须处理外部联接,事情会变得更加复杂。