1.关联查询优化

保证被驱动表的JOIN字段已经创建了索引 需要JOIN 的字段,数据类型保持绝对一致。

LEFT JOIN 时,选择小表作为驱动表, 大表作为被驱动表 。

减少外层循环的次数。

INNER JOIN 时,MySQL会自动将 小结果集的表选为驱动表 。

选择相信MySQL优化策略。 能够直接多表关联的尽量直接关联,不用子查询。(减少查询的趟数)
不建议使用子查询,建议将子查询SQL拆开结合程序多次查询,或使用 JOIN 来代替子查询。

衍生表建不了索引。

2.子查询优化

MySQL从4.1版本开始支持子查询,使用子查询可以进行SELECT语句的嵌套查询,即一个SELECT查询的结 果作为另一个SELECT语句的条件。
子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作 。 子查询是 MySQL 的一项重要的功能,可以帮助我们通过一个 SQL
语句实现比较复杂的查询。但是,子 查询的执行效率不高。原因: ① 执行子查询时,MySQL需要为内层查询语句的查询结果 建立一个临时表
,然后外层查询语句从临时表 中查询记录。查询完毕后,再 撤销这些临时表 。这样会消耗过多的CPU和IO资源,产生大量的慢查询。 ②
子查询的结果集存储的临时表,不论是内存临时表还是磁盘临时表都 不会存在索引 ,所以查询性能会 受到一定的影响。 ③
对于返回结果集比较大的子查询,其对查询性能的影响也就越大。 在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询 不需要建立临时表 ,其
速度比子查询 要快 ,如果查询中使用索引的话,性能就会更好。

结论:尽量不要使用NOT IN 或者 NOT EXISTS,用LEFT JOIN xxx ON xx WHERE xx IS NULL替代

3.排序优化

① SQL 中,可以在 WHERE 子句和 ORDER BY 子句中使用索引,目的是在 WHERE 子句中 避免全表扫 描 ,在 ORDER BY 子句
避免使用 FileSort 排序 。当然,某些情况下全表扫描,或者 FileSort 排 序不一定比索引慢。但总的来说,我们还是要避免,以提高查询效率。

② 尽量使用 Index 完成 ORDER BY 排序。如果 WHERE 和 ORDER BY 后面是相同的列就使用单索引列; 如果不同就使用联合索引。

③ 无法使用 Index 时,需要对 FileSort 方式进行调优。

4.GROUP BY优化

group by 使用索引的原则几乎跟order by一致 ,group by 即使没有过滤条件用到索引,也可以直接 使用索引。

group by 先排序再分组,遵照索引建的最佳左前缀法则

当无法使用索引列,增大 max_length_for_sort_data 和 sort_buffer_size 参数的设置

where效率高于having,能写在where限定的条件就不要写在having中了

减少使用order by,和业务沟通能不排序就不排序,或将排序放到程序端去做。Order by、group
by、distinct这些语句较为耗费CPU,数据库的CPU资源是极其宝贵的。

包含了order by、group by、distinct这些查询的语句,where条件过滤出来的结果集请保持在1000行 以内,否则SQL会很慢。

5.覆盖索引

什么是覆盖索引?

理解方式一:索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它
不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数
据,那就不需要读取行了。一个索引包含了满足查询结果的数据就叫做覆盖索引。

理解方式二:非聚簇复合索引的一种形式,它包括在查询里的SELECT、JOIN和WHERE子句用到的所有列 (即建索引的字段正好是覆盖查询条件中所涉及的字段)。

简单说就是, 索引列+主键 包含 SELECT 到 FROM之间查询的列 。

覆盖索引的利弊

好处: 1. 避免Innodb表进行索引的二次查询(回表)

            2. 可以把随机IO变成顺序IO加快查询效率

弊端: 索引字段的维护 总是有代价的。因此,在建立冗余索引来支持覆盖索引时就需要权衡考虑了。这是业务 DBA,或者称为业务数据架构师的工作。

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信