**声明:****个人学习笔记,认识有限。**欢迎指正,非喜勿喷
(程序员网站的编辑器竟然这么垃圾,颜色都没有)
SQL优化是面试绕不过去的坎,最近补习了一下,将笔记记录下来。
部分程序员不善表达,水平很高,面试的时候却发挥不出来。提升自己表达的逻辑性,可以多画画思维导图,将抽象化为形象,表达的时候安装思维导图来,让人听起来很有层次逻辑感。
--------------------------------------------------------------------------------
MySQL优化按优化对象分类,可以分为库表结构优化,索引优化,查询优化****,查询优化又可以分为减少列,减少行和应用层关联。目前只看了查询优化。
一、首先要明白慢查询如何产生。
查询性能低下最基本的原因是访问的数据太多。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化:
1.确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候也可能是访问了太多的列。
2.确认MySQL服务器层是否在分析大量超过需要的数据行。
——摘自《高性能MySQL3》(第三版都是2013年的,很多优化技巧感觉有点过时了,但思想部分还是可以学习的)
-------------------------------------------------------------------------------------------
**二、**如何做
1、减少列很简单,查询字段只获取需要的字段。特别是在联表查询的时候,切忌使用 * 号
不推荐:SELECT * FROM a JOIN b using(id)
推荐:SELECT a.id FROM a JOIN b using(id)
2、减少行最简单的就是进行分页。在实际场景中,对于报表,新闻这一类,一般只看前几十行数据。
这里有一个问题:where条件 能不能减少访问的行?
一般MySQL能够使用如下三种方式应用WHERE条件,从好到坏依次为:
①在索引中使用WHERE条件来过滤不匹配的记录。这是在存储引擎层完成的。
②使用索引覆盖扫描(在Extra列中出现了Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中 的结果。这是在 MySQL服务器层完成的,但无须再回表查询记录。
③从数据表中返回数据,然后过滤不满足条件的记录(在Extra列中出现Using Where)。这在MySQL服务器层完 成,MySQL需要先从数据表读出记录然后过滤。 ——摘自《高性能MySQL》
上诉 where条件 的工作方式,再一次说明了索引的重要性。
3、分解关联查询:单表查询查出数据,在应用层进行联表操作。一张表对应一个查询SQL,对应一个实体类(这跟我上篇笔记对实体类的理解不谋而合了)。优点:
①让缓存效率更高,因为一张表的数据都是从一个SQL查出来的,缓存命中跟高了。
②执行单个查询可以减少锁的竞争。
③将多表查询拆成单表查询,也是一种解耦合的思想,实现了SQL的复用,提高了可扩展性。
④可以减少冗余记录的查询。在应用层做关联查询,意味着对于某条记录应用只需要查询一次,而在数据库中做 关联查询,则可能需要重复地访问一部分数据。
这里还有一个问题是:假如要查询 a 表和 b 表。
第一种方案:一次性查出 两张表的数据,使用双重 for 循环在应用层做匹配。
第二种方案:先查出 a 表的数据,然后多次去 b 表查询。
虽然两种方案时间复杂度都是 N^2 ,但各自消耗的资源不一样,这就需要自己斟酌了。
**三、**Hash Join
在MySQL 8 终于引入了Hash Join 算法,联表查询和**分解关联查询,**谁更胜一筹呢?