导图社区 MySQL详细版
这是一个关于MySQL详细版的思维导图,梳理了MySQL的关键技术点,主要涵盖存储引擎、索引机制、数据库优化三大模块,适合作为性能调优和架构设计的参考指南。
编辑于2025-11-20 17:09:01MySQL
MySQL是一种流行的开源关系型数据库管理系统,它支持大量的用户并发访问和大规模数据处理。 MySQL以其高效、可靠、易于使用及灵活的配置选项而广受企业和个人开发者青睐。无论是构建复杂的企业级应用还是简单的个人项目,MySQL都是管理数据的强大工具。
引擎
索引
为什么要使用索引
索引是什么
索引的本质
索引是数据结构
排好序的快速查找的数据结构
索引是在存储引擎中实现的
存储引擎可以定义每个表的
最大索引数
最大索引长度
不同的引擎创建的索引是不同的
优点
提升效率,降低数据库的IO成本
通过创建唯一索引,可以保证数据的唯一性
加速表和表之间的连接
对于有依赖关系的子表和父表联合查询时提升效率
使用分组和排序子句进行数据查询时,可以显著减少查询中分组和排序的时间
缺点
创建索引和维护需要耗费时间
索引需要占用磁盘空间
虽然提升了查询速度,但是降低了更新表的速度
对表中的数据做新增修改删除时因为要动态的维护索引所以降低了效率
所以如果有大量的数据需要修改的时候,可以先删除索引,完成数据更新后,在创建索引
索引的推演
没有索引之前的查找
在一个数据页中
以主键为搜索条件
二分法
其他条件
最小记录
依次遍历
多个数据页中
只能先定位到所在数据页
从所在页内查找
都是依次遍历
查询效率低下
索引方案
核心概念
数据页
组成
record_type
概念
记录头信息的属性
普通的用户记录
0
目录项
1
最小值
2
最大值
3
next_record
相对于本条记录的下一条记录的地址偏移量
目录页
与数据页的区别
record_type
1
存放的数据
最小值
实际地址
关键技术点
用主键值的大小为数据页中的记录排序
双向链表
为什么要用链表
因为在实际的内存空间中要单独开辟出一大段单独的空间存放数据比较浪费空间
所以用单向链表是:逻辑上连续空间,不是实际内存中的连续空间
给所有存放数据的页建立一个目录项
key
当前目录项记录中最小值
多个目录项用key的大小 从小到大排序
page_no
数据页的实际地址
索引的类型
功能逻辑
物理实现方式
作用字段个数
单列索引
联合索引
特点
创建多个字段为一个索引
最多16个
阿里建议在5个以内
建立在多列上的索引
index(a,b,c)
数据结构
B+树
基于多个字段构建B+树
构建B+树的排序方式
按照字段排序
第一个字段相同时,再按照第二个字段排序,以此类推
排序效果
A:第一字段
全局有序
B:相对有序
C:相对有序
最左匹配原则
where条件后面包含联合索引第一个字段
索引的代价
空间上的成本
占用存储空间
时间上的成本
增加新增或修改的时间
总结
聚簇索引的叶子节点存储的是数据记录
非聚簇索引的叶子节点存储的是数据位置
索引的设计原则
适合加索引
字段的数值有唯一性限制
主键都是符合条件的
除主键以外
例如:学生的学号
身份证号码
业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。(来源:Alibaba)
说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的。
频繁作为where条件出现的字段
经常group by 和order by的列
update,delete的where条件
distinct字段
多表join链接操作时,创建索引注意事项
连接表的数量尽可能不要超过3张
对where条件创建索引
对用于连接的字段创建索引
使用列的类型小的创建索引
使用字符串前缀创建索引
【 强制 】在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。
说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会 高达90% 以上 ,可以使用 count(distinct left(列名, 索引长度))/count(*)的区分度来确定。
区分度高的列
使用最频繁的列放到联合索引的左侧
在多个字段都要创建索引的情况下,联合索引优于单值索引
不适合创建索引
在where中使用不到的字段,不要设置索引
数据量小的表最好不要创建索引
有大量重复数据的列上不要创建索引
避免对经常更新的表创建过多的索引
不建议用无序的值作为索引
删除不在使用或者很少使用的索引
不要定义冗余或重复的索引
数据库服务器优化
观察
慢查询
sql执行时间超过10秒会被记录为慢查询
默认值,可以修改
默认不开启
手动开启
永久生效配置(需修改配置文件)
编辑MySQL配置文件
在[mysqld]段落下添加参数
slow_query_log = ON slow_query_log_file = /var/lib/mysql/slow.log long_query_time = 1 log_queries_not_using_indexes = 1 # 记录未使用索引的SQL(可选) log_slow_admin_statements = 1 # 记录管理类慢SQL(如ALTER TABLE)
重启MySQL
sudo systemctl restart mysql # Linux
临时动态配置(无需重启)
执行SQL命令动态开启
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; -- 单位:秒 SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log';
注意:动态设置会在重启后失效,适合临时调试。
关键参数说明
long_query_time:慢查询阈值,默认10秒,建议生产环境设为1-3秒
log_queries_not_using_indexes:记录未使用索引的查询(可能产生大量日志)
min_examined_row_limit:设置扫描行数超过该值才记录(如1000)
验证配置是否生效
检查参数状态
SHOW VARIABLES LIKE 'slow_query_log'; -- 应为ON
SHOW VARIABLES LIKE 'long_query_time'; -- 确认阈值
SHOW VARIABLES LIKE 'slow_query_log_file';-- 查看日志路径
查看日志文件内容
cat /var/lib/mysql/slow.log # Linux
注意事项
日志文件需确保MySQL进程有写入权限(特别是Linux系统)
修改long_query_time后需重新连接会话才能生效
高并发场景建议设置log_throttle_queries_not_using_indexes限制日志量
生产环境建议定期清理或分割日志文件,避免磁盘占满
sql查询
位置决定效率
如果页就在缓冲池中,那么效率是最高的,否则还需要从内存或者磁盘中进行读取
批量决定效率
如果从磁盘中对单一页进行随机读,效率比较低
如果采用顺序读取的方式,批量对页进行读取,效率比较高
explain
show profiling
行动