MySQL多表查询优化

1、多表查询链接的选择:

相信这内链接,左链接什么的你们都比较熟悉了,固然还有左外链接什么的,基本用不上我就不贴出来了。这图只是让你们回忆一下,各类链接查询。 而后要告诉你们的是,须要根据查询的状况,想好使用哪一种链接方式效率更高。mysql

2、MySQL的JOIN实现原理

在MySQL 中,只有一种Join 算法,就是大名鼎鼎的Nested Loop Join,他没有其余不少数据库所提供的Hash Join,也没有Sort Merge Join。顾名思义,Nested Loop Join 实际上就是经过驱动表的结果集做为循环基础数据,而后一条一条的经过该结果集中的数据做为过滤条件到下一个表中查询数据,而后合并结果。若是还有第三个参与Join,则再经过前两个表的Join 结果集做为循环基础数据,再一次经过循环查询条件到第三个表中查询数据,如此往复。 ——摘自《MySQL 性能调优与架构设计》laravel

3、补充:mysql对sql语句的容错问题

即在sql语句不彻底符合书写建议的状况,mysql会容许这种状况,尽量解释它:面试

1)通常cross join后面加上where条件,可是用cross join+on也是被解释为cross join+where;算法

2)通常内链接都须要加上on限定条件,如上面场景一;若是不加会被解释为交叉链接;sql

3)若是链接表格使用的是逗号,会被解释为交叉链接;shell

注:sql标准中还有union join和natural inner join,mysql不支持,并且自己也没有多大意义,其实就是为了“健壮”。可是其实结果能够用上面的几种链接方式获得。数据库

3、超大型数据尽量尽力不要写子查询,使用链接(JOIN)去替换它:

固然,关于这句话,也不必定就全是这样。服务器

1)由于在大型的数据处理中,子查询是很是常见的,特别是在查询出来的数据须要进一步处理的状况,不管是可读性仍是效率上,这时候的子查都是更优。架构

2)然而在一些特定的场景,能够直接从数据库读取就能够的,好比一个表(A表 a,b,c字段,须要内部数据交集)join本身的效率必然比放一个子查在where中快得多。并发

4、使用联合(UNION)来代替手动建立的临时表

UNION是会把结果排序的!!!

union查询:它能够把须要使用临时表的两条或更多的select查询合并的一个查询中(即把两次或屡次查询结果合并起来。)。在客户端的查询会话结束的时候,临时表会被自动删除,从而保证数据库整齐、高效。使用union来建立查询的时候,咱们只须要用UNION做为关键字把多个select语句链接起来就能够了,要注意的是全部select语句中的字段数目要想同。

要求:两次查询的列数必须一致(列的类型能够不同,但推荐查询的每一列,相对应的类型要同样)

能够来自多张表的数据:屡次sql语句取出的列名能够不一致,此时以第一个sql语句的列名为准。

若是不一样的语句中取出的行,有彻底相同(这里表示的是每一个列的值都相同),那么union会将相同的行合并,最终只保留一行。也能够这样理解,union会去掉重复的行。

若是不想去掉重复的行,可使用union all。

若是子句中有order by,limit,需用括号()包起来。推荐放到全部子句以后,即对最终合并的结果来排序或筛选。

注意:

一、UNION 结果集中的列名老是等于第一个 SELECT 语句中的列名

二、UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有类似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同

UNION ALL的做用和语法:

默认地,UNION 操做符选取不一样的值。若是容许重复的值,请使用 UNION ALL。当 ALL 随 UNION 一块儿使用时(即 UNION ALL),不消除重复行。

5、总结

(1)对于要求全面的结果时,咱们须要使用链接操做(LEFT JOIN / RIGHT JOIN / FULL JOIN);

(2)应尽可能避免在 where 子句中对字段进行 null 值判断,不然将致使引擎放弃使用索引而进行全表扫描,如:

备注、描述、评论之类的能够设置为 NULL,其余最好不要使用NULL。

不要觉得 NULL 不须要空间,好比:char(100) 型,在字段创建时,空间就固定了, 不论是否插入值(NULL也包含在内),都是占用 100个字符的空间的,若是是varchar这样的变长字段, null 不占用空间。

能够在num上设置默认值0,确保表中num列没有null值,而后这样查询:

select id from t where num = 0

(3)in 和 not in 也要慎用,不然会致使全表扫描,如:

对于连续的数值,能用 between 就不要用 in 了:

不少时候用 exists 代替 in 是一个好的选择:

(4)尽可能使用数字型字段,若只含数值信息的字段尽可能不要设计为字符型,这会下降查询和链接的性能,并会增长存储开销。这是由于引擎在处理查询和连 接时会逐个比较字符串中每个字符,而对于数字型而言只须要比较一次就够了。

(5)尽可能使用表变量来代替临时表。若是表变量包含大量数据,请注意索引很是有限(只有主键索引)。

(6)不要觉得使用MySQL的一些链接操做对查询有多么大的改善,其实核心是索引

以上内容但愿帮助到你们, 不少PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提高,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货须要的能够免费分享给你们 ,须要戳这里     PHP进阶架构师>>>实战视频、大厂面试文档免费获取

相关文章
相关标签/搜索