子查询 select 语句与内部连接

Sub query select statment vs inner join

我对这两个更快、更常用且最适合记忆的语句感到困惑

select p.id, p.name, w.id, w.name 
from person p 
inner join work w on w.id = p.wid 
where p.id in (somenumbers)
vs

select p.id, p.name, (select id from work where id=p.wid) , (select name from work where id=p.wid)
from person p 
where p.id in (somenumbers)

整个想法是,如果我有庞大的数据库并且我想进行内部连接,那么连接工作 table 和人员 table 将占用内存并且性能会降低,但是子查询 select 个语句,它只会 select 一个语句,所以这里最好的是

第二个示例中的子查询将对每一行执行一次,这将执行得很糟糕。也就是说,一些优化器 可能 能够为您将其转换为连接 - YMMV。

通常要遵循的一个好的规则是:更喜欢连接而不是子查询。

首先,这两个查询相同。第一个过滤掉 work.

中没有匹配行的所有行

等效的第一个查询使用 left join:

select p.id, p.name, w.id, w.name 
from person p left join
     work w
     on w.id = p.wid 
where p.id in (somenumbers);

那么,第二个查询可以简化为:

select p.id, p.name, p.wid,
       (select name from work where w.id = p.wid)
from person p 
where p.id in (somenumbers);

当 ID 已经存在于 person 中时,没有理由在 work 中查找它。

如果您想要优化查询,那么您需要 person(id, wid, name)work(id, name).

上的索引

有了这些索引,两个查询应该有基本相同的性能。子查询将使用 work 上的索引从 work 中获取行,而 where 子句将使用 person 上的索引。任何一个查询都应该是快速且可扩展的。

与 sub-query 相比,连接提供更好的性能。如果在 Int 列上有连接或在连接列上有索引,则性能最好。

select p.id, p.name, w.id, w.name 
from person p 
inner join work w on w.id = p.wid 
where p.id in (somenumbers)

这真的取决于你想如何优化查询(包括但不限于 add/removing/reordering 索引),

我发现使连接飙升的设置可能会让子查询受到影响,反之亦然。因此,将它们与相同设置进行比较没有太大意义。

我选择使用join优化。根据我的经验,在最佳条件设置下加入,很少输给子查询,但阅读起来更容易。

当供应商将带有子查询的极端查询负载塞入系统时。除非性能开始爬行,否则由于我其他工作的查询优化,根本不值得更改它们。