sql_Join执行原理
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)
-
Index Nested-LoopJoin 算法(减少内层表数据的匹配次数)
前置条件:使用Index Nested-Loop Join 算法的前提是匹配的字段必须建立了索引 亮点:原来的匹配次数= 外层表行数 * 内层表 => 外层表的行数 * 内层表索引的高度
本文作者:康康滴
本文链接:https://www.cnblogs.com/kkbk/p/17701947.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。