[SQL] 将子查询改写成hash join

Posted adream307

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SQL] 将子查询改写成hash join相关的知识,希望对你有一定的参考价值。

这个是当时给新员工做培训时,我认为最难的一条 SQL语句

原始 SQL 语句

select A.a1
from A
where A.a2 > (
	select max(B.b1)
	from B
	where B.b2= A.a3
);

很多人看到这条语句时,表示不知道这条语句在干什么,这里简单解释一下:

  1. 从表A中取出一行,记为 ax1,ax2,ax3
  2. 根据ax3的值,在表B中删选出所有满足 B.b2==ax3
  3. 在第2步筛选出的表B的所有行中,选出 B.b1 的最大值,记为 maxB1
  4. 根据第1步筛选出的 ax2maxB1 值如果 ax2 > maxB1 则输出当前的 ax1,否则不输出任何东西
  5. 在从表A中取出下一行数据,再次按照 步骤1,2,3,4 计算一次

简单说就是表A 中每一行数据都需要在表B 中做一次筛选,然后再比较筛选出的 max(B.b1)

改写后的 SQL 语句

create view C(c1, c2) AS
select B.b2,max(B.b1) from B group by B.b2;

select A.a1 from A,C
where A.a3=C.c1 and A.a2 > C.c2;

以上是关于[SQL] 将子查询改写成hash join的主要内容,如果未能解决你的问题,请参考以下文章

SQL(及存储过程)跑得太慢怎么办?

Firebird hash join

将子选择 sql 查询转换为 laravel 查询

mysql 8 新特性三 Hash Join / 联接查询算法之Hash Join (五)

尝试将子表单记录源设置为 sql 查询时出错

帮助将子查询转换为带连接的查询