高性能 MySQL 实战


此系列教程已全部更新完毕,通过本系列教程的学习,你可以深入了解 MySQL 底层的算法、实现和原理,进而通过实战篇的演练洞察如何对 MySQL 查询进行优化、如何对数据库操作进行备份和回撤、以及如何进行主从复制和读写分离,从而打造出高性能、高可用的 MySQL 集群。

你需要升级为订阅用户才能阅读所有教程内容,可以通过点击下面的按钮按照提示升级为订阅用户(已经是订阅用户忽略):

立即升级为订阅用户

内容规划暂定如下:

整体架构

索引和查询优化

查询小技巧分享:对于 count 聚合查询,有同学可能会好奇到底使用 count(*) 还是 count(id) 查询性能好一些,对于 InnoDB 引擎而言,MySQL 专门对 count(*) 做了优化,而 count(id) 则会进行全表扫描,再逐行累加,因此推荐使用 count(*)。有人可能会困惑,为啥 InnoDB 不像 MyISAM 那样把全表记录数记录下来,因为 InnoDB 支持事务,而事务里面有个 MVCC 机制(下面的事务篇里面会详细介绍),每条记录可能同时存在多个版本,因此,具体有多少行是不确定的。另外,对于经常需要计数的表字段,我们在设计数据表时会基于反范式设计通过冗余字段来存储,比如文章浏览数、视频观看数、商品购买数等,或者通过缓存系统来保存,这些手段都是为了提升查询性能。

数据库事务篇

注:以下事务篇教程仅限 InnoDB 引擎。

MySQL 事务如何在可重复读级别解决幻读问题:我们知道 InnoDB 支持行锁,在更新(修改/删除)某一行之前可以先通过行锁进行加锁操作,但是对于插入操作而言,事先插入的行是不存在的,也就无法加行锁,为此 MySQL 引入了一个间隙锁(Gap Lock)的概念,即对待插入的行与行之间的间隙进行加锁(两端是(-∞,MIN) 和 (MAX,+∞)),一个相邻的间隙锁和行锁合起来形成一个 Next-key Lock,它是一个前开后闭的区间(间隙锁+行锁),Next-key Lock 是 MySQL 加锁的基本单位,并且查询过程中访问到的对象才会加锁,如果一个 SQL 加锁语句查询条件包含唯一索引(包括主键)的等值查询,则该锁退化为行锁,因此对于一个插入语句而言,由于设置了 Next-key Lock,因此可以阻塞其他事务对对应行和间隙的读操作,从而避免了幻读问题。

数据库高可用篇

运维小技巧分享之删库不一定要跑路篇:binlog 日志除了用作数据库高可用集群构建之外,还可以用来恢复误删除的数据,如果误删除的是某个数据行的话,可以使用 Flashback 工具结合日志格式为 ROW 的 binlog 来恢复对应数据;如果误删除的是数据库/表的话,可以基于全量备份(定时备份的整个数据库数据)+增量备份(binlog)恢复对应数据;如果误删除的是整个数据库实例的话(通过 rm 之类的磁盘文件删除命令),如果已经基于 binlog 构建了数据库集群的话,这个最不用担心,只需摘除这个节点然后将其他节点数据同步过来即可。

实战优化篇

注:以下实战优化篇以 Laravel 模型类数据库操作为例进行演示

日常数据库优化建议:通过高级的数据库设计让 SQL 查询语句变得简单易优化,而不是堆砌复杂的难以优化的 SQL 语句才能获取到数据。


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 没有上一篇了

>> 下一篇: MySQL 数据库安装和服务端启动原理