MySQL优化是后端开发者的必备技能,但很多人不知道从哪学起,觉得优化很深奥,是DBA才需要懂的东西。我以前也是这样,觉得MySQL优化就是加索引,加了索引就万事大吉了。直到有一次线上数据库慢查询导致服务卡顿,我才意识到自己对MySQL优化知之甚少。

从那以后我开始系统学习MySQL优化,从一个只会写CRUD的新手,到能独立做数据库优化,走了不少弯路,也总结了一些经验。今天分享我的MySQL 8.0优化学习路线,从基础到进阶,包括要学什么、怎么学、有哪些资源,以及常见的误区。希望能帮正在学MySQL优化的朋友少走弯路。

先说明一下,我是后端开发者,不是专职DBA,所以这个学习路线是从开发者的角度出发的,重点是应用层的优化,不是数据库底层的运维和调优。

一、为什么要学MySQL优化

在说学习路线之前,先说说为什么开发者要学MySQL优化。

第一,面试刚需。现在后端面试,MySQL优化几乎是必考题。索引原理、慢查询优化、事务隔离级别、锁机制,这些都是高频面试题。不懂MySQL优化,面试很容易挂。

第二,工作必备。做后端开发,每天都和数据库打交道。写的SQL好不好,索引建得对不对,直接影响系统性能。一个慢查询可能把整个服务拖垮。懂优化的开发者,写出来的代码质量更高,系统更稳定。

第三,性能瓶颈往往在数据库。一个系统的性能瓶颈,十有八九在数据库。应用服务器可以横向扩展,但数据库扩展成本高。所以优化数据库是提升系统性能最有效的方式之一。

第四,职业发展。只会写CRUD的开发者很容易被替代,懂数据库优化、能解决复杂性能问题的开发者更有竞争力,薪资也更高。

二、学习路线总览

我的学习路线分四个阶段:基础阶段、索引阶段、进阶阶段、实战阶段。每个阶段有不同的重点和目标。

基础阶段:搞懂MySQL的基本概念和架构,知道一条SQL是怎么执行的。

索引阶段:深入理解索引原理,学会建索引和用索引。

进阶阶段:学习事务、锁、优化器、慢查询分析等进阶知识。

实战阶段:通过真实案例练习优化能力,形成系统化的优化方法论。

下面详细说每个阶段学什么。

三、第一阶段:基础

基础阶段的目标是搞懂MySQL的基本架构和一条SQL的执行流程。这是后面所有优化的基础。

1. MySQL的整体架构

要知道MySQL分Server层和存储引擎层。Server层包括连接器、查询缓存、分析器、优化器、执行器等,存储引擎层负责数据的存储和读取,最常用的是InnoDB。

要搞清楚每个组件的作用:连接器负责连接管理和权限验证,查询缓存(MySQL 8.0已经移除了),分析器负责词法分析和语法分析,优化器负责生成执行计划,执行器负责调用存储引擎执行。

2. InnoDB存储引擎

InnoDB是MySQL 8.0的默认存储引擎,要重点学。要了解InnoDB的特点:支持事务、支持行锁、支持外键、聚簇索引、MVCC等。

要了解InnoDB的存储结构:表空间、段、区、页。知道数据是怎么存在磁盘上的,页是InnoDB磁盘管理的最小单位,默认16KB。

3. 一条SQL的执行流程

这是最重要的基础。要能说清楚一条SELECT语句从客户端发出去,到结果返回,中间经过了哪些步骤。一条UPDATE语句又有什么不同,涉及到redo log、undo log、binlog等。

搞懂了执行流程,后面学优化的时候就知道每个环节可以怎么优化。

4. 数据类型和表设计

优化从表设计开始。要知道常用数据类型的区别和选择原则:INT和BIGINT怎么选,VARCHAR和CHAR怎么选,DECIMAL和FLOAT的区别,日期类型怎么选等。

好的表设计能从根源上避免很多性能问题。比如字段不要允许NULL(NULL会导致索引失效、统计不准),用小而简单的数据类型,避免过度设计等。

学习资源:

  • 《MySQL必知必会》:入门书,快速掌握基本SQL语法
  • MySQL官方文档:最权威的资料
  • 极客时间《MySQL实战45讲》:林晓斌写的,非常好的MySQL课程,强烈推荐

四、第二阶段:索引

索引是MySQL优化的核心,也是面试最高频的考点。这个阶段要深入理解索引原理,学会正确建索引和用索引。

1. 索引的本质和数据结构

要搞懂索引是什么:索引是帮助MySQL高效获取数据的数据结构。要知道为什么用B+树而不是二叉树、红黑树、B树。B+树的特点:非叶子节点只存键值,叶子节点存数据和指针,叶子节点之间用双向链表连接。

要理解聚簇索引和非聚簇索引的区别。InnoDB的主键索引是聚簇索引,叶子节点存整行数据;二级索引的叶子节点存主键值,需要回表查询。

2. 索引的分类和使用

要知道主键索引、唯一索引、普通索引、联合索引、覆盖索引、前缀索引等的区别和使用场景。

重点是联合索引,要理解最左前缀原则。联合索引(a,b,c),能用到a、a,b、a,b,c三种查询,b、c、b,c用不到索引。还要理解索引下推(ICP),MySQL 5.6引入的优化,能在索引遍历过程中就过滤条件,减少回表次数。

3. 索引失效的场景

要知道哪些情况会导致索引失效:对索引列做函数运算、隐式类型转换、like以%开头、OR连接的条件有非索引列、不符合最左前缀等。这些都是面试常考的,也是实际开发中经常犯的错。

4. 怎么建索引

要学会根据查询场景建索引。建索引的原则:出现在WHERE、ORDER BY、GROUP BY、JOIN ON后面的列考虑建索引;区分度高的列适合建索引;不要建太多索引(索引会降低写入性能,占用空间);联合索引要把区分度高的列放前面。

还要知道怎么看执行计划(EXPLAIN),判断SQL有没有用到索引,type字段、key字段、rows字段、Extra字段分别代表什么。

学习资源:

  • 《高性能MySQL》:经典书,索引部分讲得很详细
  • 《MySQL实战45讲》:索引相关的几讲非常精彩
  • 网上的技术博客:美团、阿里等大厂的技术博客有很多MySQL优化的文章

五、第三阶段:进阶

进阶阶段学习事务、锁、优化器、慢查询分析等更深入的知识。

1. 事务和隔离级别

事务的ACID特性:原子性、一致性、隔离性、持久性。要知道每个特性是怎么实现的:原子性靠undo log,持久性靠redo log,隔离性靠锁和MVCC,一致性靠前面三者共同保证。

事务隔离级别:读未提交、读已提交、可重复读(InnoDB默认)、串行化。要知道每个隔离级别会出现什么问题(脏读、不可重复读、幻读),以及InnoDB是怎么解决这些问题的(MVCC解决不可重复读,next-key lock解决幻读)。

2. MVCC(多版本并发控制)

MVCC是InnoDB的核心特性,让读写不冲突,提升并发性能。要理解MVCC的实现原理:隐藏字段(trxid、rollpointer)、undo log版本链、Read View。要知道在可重复读和读已提交下,Read View的生成时机不同,导致可见性判断不同。

3. 锁机制

要了解InnoDB的锁:共享锁(S锁)、排他锁(X锁)、意向锁、记录锁、间隙锁、next-key lock。要知道什么情况下会加什么锁,怎么避免死锁。

间隙锁是InnoDB在可重复读隔离级别下为了解决幻读引入的,也是很多死锁和性能问题的根源,要重点理解。

4. 日志系统

要搞懂redo log、undo log、binlog的区别和作用。redo log是物理日志,保证持久性,循环写;undo log是逻辑日志,保证原子性和MVCC;binlog是逻辑日志,用于主从复制和数据恢复。

要知道两阶段提交(2PC):redo log prepare -> binlog write -> redo log commit,保证redo log和binlog的一致性。

5. 慢查询分析

要学会怎么发现和分析慢查询:开启慢查询日志,用mysqldumpslow或pt-query-digest分析慢查询日志,用EXPLAIN看执行计划,用SHOW PROFILE看每个阶段的耗时,用performance_schema分析性能瓶颈。

学习资源:

  • 《高性能MySQL》:事务、锁、优化部分都很详细
  • 《MySQL技术内幕:InnoDB存储引擎》:深入InnoDB底层原理
  • 《MySQL实战45讲》:事务、锁、日志部分讲得很透彻

六、第四阶段:实战

实战阶段是把学到的知识用到真实场景中,形成系统化的优化方法论。

1. 慢查询优化实战

找一些真实的慢查询案例,一步步分析优化。优化的思路:先看执行计划,判断有没有用到索引,扫描了多少行;然后分析为什么索引失效或者没有索引;再考虑怎么加索引或者改写SQL;最后验证优化效果。

可以在自己的项目中找慢查询,也可以在网上找案例练习。优化得多了,就会形成感觉,看到一条SQL大概就知道有没有问题。

2. 索引设计实战

针对一个具体的业务场景,设计表结构和索引。考虑有哪些查询场景,每个查询的WHERE条件、排序字段是什么,然后设计联合索引。要权衡查询性能和写入性能,不要过度索引。

3. 死锁分析和解决

学习怎么分析死锁:用SHOW ENGINE INNODB STATUS查看死锁日志,分析是哪两个事务、哪些锁导致的死锁,然后想办法避免。常见的避免死锁的方法:固定访问顺序、缩短事务、降低隔离级别、合理建索引等。

4. 数据库性能监控

学习怎么监控数据库性能:QPS、TPS、连接数、慢查询数、锁等待、缓冲池命中率等指标。用Prometheus+Grafana做监控大盘,设置告警。知道每个指标的正常范围,出现异常能快速定位问题。

七、常见的学习误区

最后说说我踩过的学习误区,帮大家避免。

误区一:只背概念不理解原理。 很多人学MySQL优化就是背面试题,背索引失效的场景、背隔离级别,但不理解为什么。这样面试可能能过,但实际遇到问题还是不会分析。一定要理解原理,知道为什么会这样。

误区二:只看书不实践。 看书看视频觉得都懂了,但一到实际就不会用。一定要动手实践,在自己的数据库里建表、写SQL、看执行计划、做优化实验。实践出真知,优化能力是练出来的,不是看出来的。

误区三:过度优化。 不是所有SQL都要优化到极致,优化是有成本的。要先找到真正的性能瓶颈,优先优化影响大的慢查询。不要为了优化而优化,在系统还没出现性能问题的时候,保持简洁合理的设计就好。

误区四:只加索引不看执行计划。 很多人优化就是加索引,加完就觉得完事了,不看执行计划验证。有时候加了索引也不一定用到(比如隐式类型转换),或者优化器选了别的索引。一定要用EXPLAIN验证,确认索引真的生效了。

误区五:忽略业务场景。 优化不能脱离业务场景。同一个SQL,在不同的数据量、不同的查询频率下,优化策略可能完全不同。要结合业务场景来优化,不要纸上谈兵。

八、学习时间规划

给一个大概的时间规划,供参考:

  • 基础阶段:2到3周,搞懂架构和执行流程
  • 索引阶段:3到4周,深入理解索引,大量练习EXPLAIN
  • 进阶阶段:4到6周,学事务、锁、MVCC、日志
  • 实战阶段:持续进行,在工作中不断练习

总共大概3个月能入门,然后在工作中持续积累。MySQL优化是一个长期的过程,不是学完就结束了,要不断学习新版本的特性(MySQL 8.0有很多新特性,比如窗口函数、CTE、不可见索引、降序索引等),不断积累实战经验。

九、写在最后

以上就是我的MySQL 8.0优化学习路线。从基础到进阶再到实战,一步步来,不要急于求成。MySQL优化没有捷径,需要理解原理加上大量实践。

对于后端开发者来说,MySQL优化是必须掌握的核心技能。投入时间学习MySQL优化,回报率很高,不管是面试还是工作,都能让你脱颖而出。

2021年了,MySQL 8.0已经很成熟了,新特性很多,性能也比5.7好很多。如果还在用5.7,建议升级到8.0,体验会好很多。

最后推荐几本书和课程:《MySQL必知必会》入门,《高性能MySQL》深入,《MySQL技术内幕:InnoDB存储引擎》底层原理,极客时间《MySQL实战45讲》强烈推荐。这些资源配合起来学,效果很好。

希望这篇学习路线能帮到正在学MySQL优化的朋友。如果有问题或者更好的学习方法,欢迎在评论区交流。祝大家都能成为MySQL优化高手。