MySQL复杂SQL大多数场景都是多表关联,那么多表关联是先连表还是先查询条件,这对优化多表关联很重要,而在这优化之前,我们需要了解常见的多表关联方式有哪些呢?
一、inner join(内连接)
返回两个或多个表中满足联接条件的记录。如果左表中的行在右表中没有匹配,则不会出现在结果集中;反之亦然。
适用于查询两表中都有的匹配数据,例如用户表和订单表,查询有下单记录的用户及其订单信息。
性能上,inner join 是性能最佳的关联类型,因为只处理匹配的数据。
内连接分为三类
1、等值连接:ON A.id=B.id
2、不等值连接:ON A.id > B.id
3、自连接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid
二、left join(左连接)
返回左表的所有记录,以及右表中匹配的记录。如果右表中没有匹配记录,则结果中右表的部分将为 NULL。
适用于查询主表(左表)的所有记录,同时附加右表的匹配信息,例如查询所有用户,包括没有订单的用户。
left join 的性能比 inner join 稍差,因为需要扫描左表所有记录。
例如:SELECT * FROM a LEFT JOIN b ON a.aID =b.bID 。
解释:LEFT JOIN 是以 a 表的记录为基础的,a 表可以看成左表,b 表可以看成右表,LEFT JOIN 是以左表为准的,换句话说,左表 a 的记录将会全部显示出来,而右表 b 只会显示符合搜索条件的记录(例子中为:a.aID = b.bID),即取左边表的所有记录和右边表的交集。
LEFT JOIN 一般配合 on 和 where 使用,二者的区别是:
on :关联条件不影响左表全部信息显示,它是作为右表是否符关联条件,不符合的,右边将由 NULL 填充。
where :不关心 JOIN 类型,在关联后的虚拟表V基础上再进行条件过滤,只返回符合条件的数据行。
三、right join(右连接)
返回右表的所有记录,以及左表中匹配的记录。如果左表中没有匹配记录,则结果中左表的部分将为 NULL。
适用于查询从表(右表)的所有记录,同时附加左表的匹配信息,例如查询所有订单,包括未关联用户的订单。
RIGHT JOIN 的性能与 LEFT JOIN类似,但通常推荐通过交换表位置改为LEFT JOIN。
四、full outer join(全外连接)
返回两个表的所有记录,未匹配的部分用 NULL 填充。
MySQL 不直接支持 FULL OUTER JOIN,但可以通过 UNION 实现:LEFT JOIN 和 RIGHT JOIN 的结果合并。
适用于需要获取两个表中所有记录的情况。
五、cross join(交叉连接)
返回两个表的笛卡尔积,即所有行的组合。
适用于需要获取两个表中所有可能的组合的情况,但性能较差,特别是在数据量大的情况下不推荐使用。
六、总结
优化多表关联查询的方法包括:
1、索引:在连接列上添加索引(如主键或外键),避免对连接列进行函数或运算操作,否则 MySQL 无法使用索引。
2、选择合适的关联方式:根据具体需求选择合适的关联方式,例如在需要查询所有用户及其订单信息时使用 INNER JOIN,在需要查询所有用户包括没有订单的用户时使用 LEFT JOIN。
3、避免笛卡尔积:尽量避免使用 CROSS JOIN 或非等值查询,特别是在数据量大的情况下,这会显著降低查询效率。
4、避免使用JOIN关联太多的表:建议不要超过5个表的JOIN操作。需要JOIN的字段,数据类型必须绝对一致。每JOIN一个表会多占用一部分内存(由“join_buffer_size”控制),会产生临时表操作,影响查询效率。