连接就是把各个表中的记录都拿出来然后依次匹配加入到结果集中。连接查询中表A与表B连接查询,表A的每条记录和表B的每条记录相互匹配的组成结果集被称为笛卡尔积。
-
连接查询过程
- 确定第一个表为驱动表,查询出驱动表中所有符合条件的结果集A
- 根据上一步查询出的结果集A,循环查询第二个表(被驱动表)与结果集A匹配的记录。比如结果集A找出3条符合的记录,那么被驱动表也要根据这些过滤条件查询3次表。
-
连接分类
-
内连接:(表A inner join/cross join/join/,表B,左右表位置随意互换)驱动表中的记录在被驱动表中找不到匹配记录,该记录不加入到结果集中。
-
外连接:驱动表中的记录即使在被驱动表中没有匹配的记录,也仍要加入到结果集中
-
左连接:(表A left join 表B on 条件)左侧表表A为驱动表
-
右连接:(表A right join 表B on 条件)右侧表表B为驱动表
-
但是使用外连接时不想把不匹配的空记录放到结果集中,可以更改筛选条件子句的使用方式达成。
- where:不论内外连接,不符合条件的都不会被加入到结果集中
- on:如果无法在被驱动表中找到过滤条件的记录,对应的被驱动表记录的列置为null放入到结果集中
-
-
连接原理
- 嵌套循环连接
- 步骤1:选取驱动表,使用与驱动表相关的过滤条件,选取代价最低的单表访问方法来执行对驱动表的单表查询。
- 步骤2:对上一步骤中查询驱动表得到的结果集中每一条记录,都分别到被驱动表中查找匹配的记录。
- 索引加快连接速度
被驱动表使用到的搜索条件列置为索引列,二级索引+回表的代价低于全表扫描更低时才会使用索引;
-
基于块的嵌套循环连接
- 将表从磁盘加载到内存中,如果内存不足会先加载部分,等到加载到后面的记录时释放前面的记录
- join buffer(默认256kb,join_buffer_size配置):执行查询前申请一块固定大小的内存,然后把驱动表查出的结果集(只放入查询列和条件列,所以尽量不要*查询)记录装在里面,每条被驱动表的记录一次性和join buffer中的多条驱动表记录做匹配,做完匹配后的一条记录会从内存中清除。
-
连接优化
以上三种连接方法,最优是给被驱动表加上效率高的索引,其次是为机器调大join_buffer_size,只能选用一种。