4、sql_Join执行原理

发布时间 2023-09-14 11:02:25作者: 蛋蛋十二月

JOIN执行过程:(sql的执行过程类似Linq)

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

(两种)

如果条件中同时有on和where 条件:
SQL的执行实际是两步
    第一步:根据on条件得到一个临时表
    第二步:根据where 条件对上一步的临时表进行过滤,得到最终返回结果。
如果条件中只有on:
	那么得到的临时表就是最终返回结果
	
	
	重点:当连接查询有where条件时,带where条件的表是驱动表,否则是被驱动表
	
	反驳:
	驱动表的查询时就使用了where的索引字段,然后才是和其他表的on,最后时其他表的where

区分驱动表和被驱动表【驱动表循环1次,被驱动表循环1*N次】,以驱动表的结果集为循环的基础,访问被驱动表过滤数据,然后合并结果,驱动表在外循环、被驱动表在内循环。
如果还有第三张参与join查询的表,则以合并的结果为驱动表,第三张表作为被驱动表,以此类推。

left join中的左表是驱动表、右表是被驱动表,right join刚好相反。

尽量将小表作为驱动表,大表作为被驱动表;
为参加join的字段在被驱动表建立聚集索引,其次是非聚集索引;(减少回表)
https://m.sohu.com/a/583722343_374240?scm=1019.20001.946002.0.0&spm=smwp.srpage.SERP-list.20.1669467304918zWXHrDy

inner join时,MySQL会自动将小表作为驱动表,大表作为被驱动表。

https://www.jb51.net/article/236155.htm

https://zhuanlan.zhihu.com/p/386971420

cross join:结果是笛卡尔积,就是第一个表的行数乘以第二个表的行数。

笛卡尔积 (连表查询不加条件就会产生如:)

# 这三者效果一样,只要不写条件,就产生笛卡尔积,结果集的数量一样。
select * from t1, t2;
# 内连接
select * from t1 inner join t2;
# 全连接
select * from t1 cross join t2;

所以在连接时过滤掉特定的记录组合是很有必要的,为了避免笛卡尔积,一定要在表连接的时候加上条件!

注意:先说明条件的概念,要区分什么是连接条件和过滤条件!!

连接条件是针对两张表而言的,比如t1.m1 = t2.m2、t1.n1 > t2.n2,表达式两边是两个表的字段比较。

过滤条件是针对单表而言的,比如t1.m1 > 1是针对t1表的过滤条件,t2.n2 < 'd'是针对t2表的过滤条件。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Mysql中的Join算法https://zhuanlan.zhihu.com/p/54275505)

  1. Index Nested-LoopJoin 算法(减少内层表数据的匹配次数)

    前置条件:使用Index Nested-Loop Join 算法的前提是匹配的字段必须建立了索引
    亮点:原来的匹配次数=  外层表行数 * 内层表 => 外层表的行数 * 内层表索引的高度
    

https://www.cnblogs.com/shujiying/p/14171965.html