SQL在具有条件的表之间连接

时间:2014-01-26 20:00:17

标签: sql oracle join

我正在考虑哪些应该是在某些条件下在2个或更多表之间进行连接的最佳方式(考虑执行时间)。我有这三种方式:

第一种方式:

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

考虑表中有超过1百万行。

你有什么看法?哪个应该是正确的方式,如果存在?

3 个答案:

答案 0 :(得分:2)

通常将条件置于where子句或join条件中的内连接没有明显的差异 如果使用外连接,则将条件放在where子句中可以缩短查询时间,因为在where子句中使用condition时 左外连接,不满足条件的行将从结果集中删除,结果集变小。 但是如果在左外连接的join子句中使用条件,则与在where子句中使用条件相比,没有行删除,结果集更大。 有关更多说明,请按照示例进行操作。

创建表A

(   ano NUMBER,

aname VARCHAR2(10),

rdate DATE )

----数据

插入A 从双重中选择1,'Amand',to_date('20130101','yyyymmdd'); 提交;

插入A 选择2,'Alex',to_date('20130101','yyyymmdd')来自dual; 提交;

插入A 从双重选择3,'天使',to_date('20130201','yyyymmdd');

提交;

创建表B

(   bno NUMBER,

bname VARCHAR2(10),

rdate DATE )

插入B 从双重中选择3,'BOB',to_date('20130201','yyyymmdd'); 提交;

插入B 从双重中选择2,'Br',to_date('20130101','yyyymmdd'); 提交;

插入B 从双重中选择1,'Bn',to_date('20130101','yyyymmdd'); 提交;

首先,我们有正常的查询,它们将2个表相互连接起来:

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子句中以便具有最小的中间结果行数: (http://www.dba-oracle.com/art_dbazine_oracle10g_dynamic_sampling_hint.htm

2 - 在使用外部联接的情况下,每当您不关心精确结果行计数时(不关心表A中没有配对记录的表A的缺失记录和表B的字段将为空对于结果集中的这些记录,将条件放在where子句中以删除一组不符合条件的行,并通过减少结果行计数显着改善查询时间。

但在特殊情况下,您必须将条件放在连接部分。例如,如果您希望结果行计数等于表'A'行计数(这种情况在ETL过程中很常见),您必须将条件放在join子句中。

很多可靠的资源和专家程序员都推荐使用3-avoid子查询。它通常会增加查询时间,只要结果数据集很小就可以使用子查询。

我希望这会有用:)

答案 1 :(得分:0)

1M行确实不是 - 特别是如果你有合理的索引。我首先要让您的查询尽可能易读和可维护,并且只有在您发现查询出现问题时才开始优化(正如Gordon Linoff在他的评论中所说的那样 - 这三者之间甚至存在差异,这是值得怀疑的)。

这可能是一个品味问题,但对我来说,第三种方式似乎很笨拙,所以我会把它划掉。就个人而言,我更喜欢使用JOIN语法来加入逻辑(即,A和B的行如何匹配)和WHERE进行过滤(即,一旦匹配,哪些行感兴趣),所以我想走第一条路。但同样,它真的归结为个人品味和偏好。

答案 2 :(得分:0)

您需要查看查询的执行计划,以判断哪个计算效率最高。正如评论中指出的那样,您可能会发现它们是等效的。以下是Oracle execution plans的一些信息。根据您使用的编辑器/ IDE,可能是此的快捷方式,例如PL / SQL Developer中的F5。