上回介绍了外连接消除技术。今天更进一步来聊聊这个话题。
select * from a
right join b on a.m1 = b.m1
left join c on c.c1 = b.c1
where c.c1 in (1,2,3);
基于外连接消除技术,这个语句 left join
可以改写成 inner join
:
select * from a
right join b on a.m1 = b.m1
inner join c on c.c1 = b.c1
where c.c1 in (1,2,3);
原因是,left join 的结果中可能会有 c 的 NULL 行,但是最后通过 where 条件,这些 NULL 行肯定会被 where 过滤,所以等价于 inner join 行为。
进一步地,考虑到 where 条件过滤性可能非常好,会让 c 的结果集非常小。那么,可以让 b 先和 c 做 inner join,然后再去和 a 做 right join。改写如下:
select * from b
inner join c on c.c1 = b.c1
left join a on a.m1 = b.m1
where c.c1 in (1,2,3);
改写成这样后,b 先和 c join,可以得到一个很小的结果集,然后再用 Nested Loop Join 去和 a 做 join,性能会优得多。
-END