编写这样的查询有多好?

How good is it to write a query like this?

select 
a,
b,
(select x from table3 where id = z.id) as c,
d
from 
table1 z, table2 zz
where z.id = zz.id;

我知道可以像下面这样轻松简化查询:

select a,
b,
c.x,
d
from
table1 z,table2 zz, table3 c,
where z.id = zz.id and z.id = c.id;

但我想知道 case1 中的性能影响或额外执行是什么,或者它们都具有相同的性能?求知识而已。

具有相关子查询的第一个查询将始终 return 数据,即使 table3 为空也是如此。您需要外部联接才能获得相同的结果:

select a,
       b,
       c.x,
       d
from table1 z
join table2 zz on z.id = zz.id
left join table3 c on z.id = c.id

使用 join 查询更具可读性

但性能是一样的

select a,
b,
c.x,
d
from table1 z
join table2 zz on z.id = zz.id
join table3 c on z.id = c.id;

如果你想使用相关子查询(这很好),那么你应该这样做:

select a, b,
       (select t3.x from table3 t3 where t3.id = z.id) as c,
       d
from table1 z join
     table2 zz
     on z.id = zz.id;

重要变化:

  • 限定所有列名(我不知道abd来自哪里)。
  • 使用显式 join.

您也可以将此查询写为:

select a, b, t3.x, d
from table1 z join
     table2 zz
     on z.id = zz.id left join
     table3 t3
     on t3.id = z.id;

此查询与上一个查询略有不同。如果子查询 return 超过一行,前一个将 return 出错。这个会将每个这样的值放在不同的列中。

也就是说,Oracle 优化器非常好。如果有任何明显的性能差异,我会感到惊讶。

如果您的子查询 return 是基于单个输入的单个值,则它是标量子查询。标量子查询可能会提高查询的性能。它将在几个基本条件下这样做。首先,如果 z.id 的可能值数量相对较少。如果我没记错的话,标量子查询处理将缓存最多 254 个值。其次,如果查询的其余部分是 returning 相对较多的行数。在这种情况下,如果您只有 return 几行,那么缓存将没有机会提供帮助。但是,如果您 return 有很多行,缓存的好处就会增加。

其他人已经强调了您的原始查询如何不完全相同。

在此处查看有关标量子查询的更多信息 -> Scalar Subqueries