MySQL 核心知识与索引优化全解析

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDSClaw,2核4GB
RDS AI 助手,专业版
简介: 本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。索引优化部分,列出了索引创建的六大原则

一、MySQL 基础概念解析

  1. char 与 varchar 的区别两者都是存储字符串的类型,但核心差异体现在存储方式和性能上:
  • char是定长字符串,无论实际存储的字符串长度如何,都会占用固定长度的存储空间。例如定义char(10),即使只存 “abc” 3 个字符,也会占用 10 个字符的空间。这种特性让 char 的操作速度更快,但可能造成磁盘空间浪费。
  • varchar是变长字符串,占用的空间与实际存储的字符串长度相关。例如varchar(10)存储 “abc” 时,仅占用 3 个字符的空间(额外加 1-2 字节记录长度)。它的操作速度略慢,但能节省空间。
  1. 实际使用中,固定长度的字段(如手机号char(11)、身份证号char(18))适合用 char;长度不固定的字段(如用户名varchar(50)、备注varchar(200))适合用 varchar。
  2. 事务及四大特性事务是一组不可分割的数据库操作,要么全部成功,要么全部失败,以此保证数据的正确性和完整性。其四大特性(ACID)如下:
  • 原子性:事务中的操作是最小单元,无法拆分,要么全部执行成功,要么全部回滚。
  • 一致性:事务执行前后,数据必须处于合法状态(如转账后两人总金额不变)。
  • 隔离性:多个事务并发执行时,彼此不受干扰,仿佛在独立环境中运行。
  • 持久性:事务提交或回滚后,对数据库的修改永久生效,不会因系统故障丢失。
  1. 并发事务问题及解决
    并发事务可能引发三类问题:
  • 脏读:事务 A 读取到事务 B 未提交的数据(若 B 回滚,A 读到的数据无效)。
  • 不可重复读:事务 A 两次读取同一记录,期间事务 B 修改并提交,导致两次结果不同。
  • 幻读:事务 A 按条件查询无数据,事务 B 插入符合条件的数据后,A 插入时发现数据已存在。
  1. 数据库通过隔离级别解决这些问题:
隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
  1. MySQL 默认隔离级别是REPEATABLE READ,它平衡了安全性和性能。隔离级别并非越高越好,例如 SERIALIZABLE 虽解决所有问题,但会导致并发性能急剧下降。

二、索引基础

  1. MySQL 索引的数据结构InnoDB 存储引擎默认使用B+tree作为索引结构,其核心特点如下:
  • 多路平衡搜索树:一个节点可存储多个 key 和指针(而非二叉树的 2 个),数据量越大,树的高度越低(通常 2-3 层),检索效率更高。
  • 数据集中存储:所有数据仅存于叶子节点,非叶子节点仅作为索引,确保检索效率稳定(无论查询哪条数据,都需遍历到叶子节点)。
  • 区间查询友好:叶子节点形成双向链表,可快速定位区间范围(如查询 “id>100 and id<200”)。
  1. 聚簇索引与二级索引
  • 聚簇索引:数据与索引存储在一起,B+tree 的叶子节点保存整行数据。一张表有且仅有一个聚簇索引,默认是主键索引。若表无主键,MySQL 会选择第一个非空唯一索引作为聚簇索引;若仍无,则自动生成隐藏的 rowID 作为聚簇索引。
  • 二级索引(非聚簇索引):数据与索引分离存储,B+tree 的叶子节点仅保存主键(或聚簇索引值)。一张表可创建多个二级索引,查询时需通过主键关联聚簇索引获取完整数据。
  1. 例如,表user(id, name, age)中,id是聚簇索引(叶子节点存id+name+age),name是二级索引(叶子节点存name+id)。
  2. 回表查询基于二级索引查询时,需先通过二级索引获取主键,再到聚簇索引中查询完整数据,这个过程称为回表查询(需扫描两次索引,性能较低)。
  • 示例:通过name查询用户信息时,先在name二级索引中找到id=10,再到聚簇索引中查id=10对应的nameage
  • 优化方式:
  • 直接使用主键查询(避免二级索引)。
  • 创建联合索引(如(name, age)),实现 “索引覆盖”(二级索引已包含所需字段,无需回表)。
  • 启用索引下推(MySQL 5.6+):在二级索引层提前过滤数据,减少回表次数。
  1. B+tree 作为索引结构的原因对比其他结构(如二叉树、B 树),B+tree 的优势如下:
  • 树高更低:非叶子节点仅存 key 和指针(不存数据),一页(16KB)可存储更多 key(如主键为 bigint (8 字节)+ 指针 (6 字节),一页约存 1170 个 key),3 层树可容纳约 2190 万数据(1170×1170×16)。
  • 效率稳定:所有数据存于叶子节点,查询耗时固定。
  • 区间查询高效:叶子节点的双向链表支持快速范围扫描。

三、索引优化

  1. 索引创建原则
  • 为数据量大(单表超 10 万条)、查询频繁的表创建索引。
  • 优先为查询条件(where)、排序(order by)、分组(group by)字段创建索引。
  • 选择区分度高的列(如手机号,而非性别),唯一索引效率更高。
  • varchar 字段建议创建前缀索引(如name(10)),平衡索引大小和区分度。
  • 优先创建联合索引,将区分度高的字段放前面(如(name, age)(age, name)更优),减少单列索引(联合索引可覆盖更多查询场景)。
  • 索引不宜过多(维护成本高,会降低增删改效率)。
  1. 索引失效的常见场景
  • 违反最左前缀法则(联合索引需从最左列开始查询,如(name, age)索引,查询age=20会失效)。
  • 范围查询(如age>20)右侧的列无法使用索引((name, age)中,name='张三' and age>20name生效)。
  • 索引列上使用函数或运算(如substring(name, 1, 3)='张'age+1=20)。
  • 隐式类型转换(如phone=13800138000,而phone是 varchar 类型,需加引号)。
  • like 以 “%” 开头(如name like '%三',索引失效;name like '张%'则生效)。
  1. 可通过explain命令分析 SQL 执行计划,重点关注key(是否使用索引)、type(性能等级,避免all全表扫描)、extra(如Using filesort表示文件排序,需优化)。

四、SQL 性能分析及优化

  1. 定位慢 SQL
  • 工具监控:通过 SkyWalking 等链路追踪工具,查看接口耗时分布,定位慢 SQL。
  • 慢查询日志:开启 MySQL 慢查询日志(slow_query_log=1),设置阈值(如long_query_time=1秒),记录执行超 1 秒的 SQL。
  1. 分析 SQL 执行性能使用explain查看执行计划,核心字段如下:
  • key:实际使用的索引(为NULL表示未使用索引)。
  • type:查询类型(性能从优到差:NULL > system > const > eq_ref > ref > range > index > all)。
  • extra:额外信息(如Using index表示索引覆盖,Using where; Using index表示索引下推生效)。
  1. SQL 优化经验
  • 表设计:选择合适类型(如tinyint存性别,date存生日),主键用递增类型(如自增 ID,避免页分裂)。
  • 索引优化:合理创建索引,避免失效场景,利用联合索引覆盖查询。
  • 架构优化:高并发场景采用读写分离(主库写,从库读);数据量超千万时,考虑分库分表(如按 ID 范围拆分)。


相关文章
|
存储 缓存 文件存储
如何保证分布式文件系统的数据一致性
分布式文件系统需要向上层应用提供透明的客户端缓存,从而缓解网络延时现象,更好地支持客户端性能水平扩展,同时也降低对文件服务器的访问压力。当考虑客户端缓存的时候,由于在客户端上引入了多个本地数据副本(Replica),就相应地需要提供客户端对数据访问的全局数据一致性。
32689 78
如何保证分布式文件系统的数据一致性
|
前端开发 容器
HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第8章FlexBox布局(上)
HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第8章FlexBox布局
17740 19
|
设计模式 存储 监控
设计模式(C++版)
看懂UML类图和时序图30分钟学会UML类图设计原则单一职责原则定义:单一职责原则,所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。bad case:IPhone类承担了协议管理(Dial、HangUp)、数据传送(Chat)。good case:里式替换原则定义:里氏代换原则(Liskov 
36674 19
设计模式(C++版)
|
存储 编译器 C语言
抽丝剥茧C语言(初阶 下)(下)
抽丝剥茧C语言(初阶 下)
|
机器学习/深度学习 人工智能 自然语言处理
带你简单了解Chatgpt背后的秘密:大语言模型所需要条件(数据算法算力)以及其当前阶段的缺点局限性
带你简单了解Chatgpt背后的秘密:大语言模型所需要条件(数据算法算力)以及其当前阶段的缺点局限性
24753 14
|
机器学习/深度学习 弹性计算 监控
重生之---我测阿里云U1实例(通用算力型)
阿里云产品全线降价的一力作,2023年4月阿里云推出新款通用算力型ECS云服务器Universal实例,该款服务器的真实表现如何?让我先测为敬!
36657 15
重生之---我测阿里云U1实例(通用算力型)
|
SQL 存储 弹性计算
Redis性能高30%,阿里云倚天ECS性能摸底和迁移实践
Redis在倚天ECS环境下与同规格的基于 x86 的 ECS 实例相比,Redis 部署在基于 Yitian 710 的 ECS 上可获得高达 30% 的吞吐量优势。成本方面基于倚天710的G8y实例售价比G7实例低23%,总性价比提高50%;按照相同算法,相对G8a,性价比为1.4倍左右。
|
存储 算法 Java
【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的限流器RateLimiter功能服务
随着互联网的快速发展,越来越多的应用程序需要处理大量的请求。如果没有限制,这些请求可能会导致应用程序崩溃或变得不可用。因此,限流器是一种非常重要的技术,可以帮助应用程序控制请求的数量和速率,以保持稳定和可靠的运行。
29834 52

热门文章

最新文章

下一篇
开通oss服务