【mysql】MySQL慢查询(三):问题解决,干货总结

标签: mysql


上篇回顾

继上两篇:

 

在以上两篇内容中,我们一起探索了这些内容:

  • SQL执行过程

  • 查询SQL为什么会慢

  • 如何定位查询问题

  • 几种实用解决方案介绍

如果将MySQL慢查询作为一个问题来拆解分析的话,之前上、中篇章算是问题分析、问题定位和解决,那今天来跟大家收下尾,聊聊MySQL慢查询问题解决经验总结。

219d6b4b-bc54-4b8c-96e5-edf113608735.png

 

废话不多说,直接开干~

高性能查询难题优化总结

我们来总结一下,应该如何处理高性能查询难题?

假如把高性能查询比作一个“难题”,它其实是包括多个子难题在内,共同作用的结果。

今天我们来归纳总结下,主要包括以下几类:

1 数据结构优化

良好的schema设计原则是普遍适用的,但是MySQL有他自己的实现细节要注意,概况来讲,尽可能保持任何东西小而简单总是好的。

主要有以下简单的原则值得你去考虑使用:

  • 尽量避免过度设计

  • 使用小而简单的合适数据类型,尽可能避免使用null

  • 尽量使用相同的数据类型存储相似或者相关的值

  • 注意可变长字符串,其在临时表和排序时可能按最大长度分配内存

  • 尽量使用整形定义标识符

     

75220f54-7286-4239-8e67-40d9a8488c66.jpg

 

2 索引设计优化

常见的B-Tree索引,按照顺序存储数据,所以MySQL可以用来做ORDER BY 和 GROUP BY操作。因为数据是有序的,所以便于将相关的列值都存储在一起。由于索引中存储了实际的列值,所以一些查询只通过索引就能够完成查询(如:聚簇索引)。

 

根据索引的特性,总结索引的优点有如下几点:

  • 减少服务器需要扫描的数据量;

  • 帮助服务器避免排序和临时表;

  • 将随机I/O变为顺序I/O。

     

编写查询语句时候应该注意尽可能选择合适的索引,以避免单行查找,尽可能使用索引覆盖。

根据执行计划依次扫描相关表中的行,不在数据缓冲区的走IO存储引擎扫描表的性能消耗参考下面的list,消耗从大到小:

全表扫描>全索引扫描>部分索引扫描>索引查找>唯一索引/主键查找>常量/null

468c4028-b487-4f14-8634-69cd77f17dd0.jpg

3 应用查询优化

应用查询优化是建立在良好的数据结构和合理的索引设计之上的。

它主要包括以下几种情况:

3.1 重构查询方式

优化慢查询时,目标应该是找到一个更优的方案来达到我们获取结果数据的目的。其中可以存在多样的权衡方案:

1)从数据库中查询计算直接获取到结果数据;

2)拆分多条子查询来逐步得到结果数据;

3)从数据库获取到基础数据,然后应用代码逻辑加工后获得结果数据。

3.2 让SQL尽量符合查询优化器的执行要求

MySQL 查询优化器并不是对所有查询都适用的,我们可以通过改写查询 SQL 来让数据库更高效的完成工作。

常见查询应用优化建议汇总如下:

1)对于任何查询,应尽量避免全表扫描

    首先应考虑在 where 及 order by 涉及的列上建立并应用索引;

2)尽量避免在 where 子句中进行操作

    使用 or 来连接条件、对字段进行 null 值判断、匹配查询 '%abc%'、!= 或 <> 操作符,否则将导致引擎放弃使用索引而进行全表扫描;

    对字段进行表达式、函数操作,这将导致引擎放弃使用索引而进行全表扫描;

3)尽量应用索引

    使用索引字段作为条件时,如果是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致;

4)索引字段要注意慎重选取

    索引尽量避开区分度不大的字段,如:sex、male、female 

    这种五五开的索引列有大量数据重复时,那么即使在 sex 上建了索引也对查询效率起不了作用。

5)一个表的索引数最好不要超过 6 个

    索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率, 因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。

6)尽量使用数字型字段

    若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。 这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

7)尽量避免使用 *

    select * from table ,用具体的字段列表代替 *,不要返回用不到的任何字段,尤其是多表关联查询的情况。

MySQL v5.6版本以后,消除了很多MySQL原本的限制,让更多的查询能够以尽可能高的效率完成。

 

ddc91445-84c8-49d0-9967-1a33471c0d1e.jpg

 

小结

良好的表结构设计是高性能查询的基石,恰当的索引设计是高性能查询的助推器,同时合理的查询应用也是必不可少的。数据结构优化、索引设计优化及应用查询优化犹如三叉戟一般,齐头并进,在高性能查询应用中缺一不可。

写在最后

全文总结一下,其实就是我们要学会用数据库的要求方式来执行SQL

即要写好应用查询SQL,必须要结合良好的数据结构和合理的索引设计才可以。

其实MySQL查询优化中的每一项拆开讲都可以是很大的章节,在此主要是将解决问题的思路分享给大家,希望能对大家今后的工作中能有所帮助。

 

最后,感谢大家的持续关注~

 - END -

 


作者:架构精进之路,专注软件架构研究,技术学习与个人成长,关注并私信我回复“01”,送你一份程序员成长进阶大礼包。



「技术架构精进」专注架构研究,技术分享

 本文分享自微信公众号 - 架构精进之路(jiagou_jingjin)。


本文出自《粉墨记忆》 => 《【mysql】MySQL慢查询(三):问题解决,干货总结
转载时请注明出处及相应链接, 本文地址:https://www.fmxk.ac.cn/?post=14

WRITTEN BY

avatar


发表评论: