MySQL 索引

1. 核心概念

  • 索引是什么 :帮助MySQL高效获取数据的有序数据结构

  • 核心作用提高查询速度降低排序成本

  • 代价 :占用额外空间,降低增、删、改的效率


2. 核心数据结构:B+Tree

  • 默认索引结构:InnoDB存储引擎默认使用B+Tree。

  • B+Tree的核心特点

    1. 所有数据都在叶子节点,非叶子节点只存索引(指针),不存数据。

    2. 叶子节点之间通过双向链表连接,便于范围查询。

  • 为什么选B+Tree,而不是其他?

    • 对比二叉树/红黑树:层级更少,IO次数更少。

    • 对比B-Tree:非叶子节点不存数据,能存放更多索引项,树更矮。

    • 对比Hash索引 :B+Tree支持范围查询排序


3. 两种最重要的索引类型

索引类型 叶子节点存储内容 特点
聚集索引 (主键索引) 整行数据 一个表只有一个,一般是主键
二级索引 (非主键索引) 主键的值 可以有多个,查询可能需要回表
  • 回表 :通过二级索引找到主键ID,再到聚集索引查询完整数据的过程。尽量用覆盖索引避免回表

4. 索引语法

4.1 创建索引

复制代码
-- 普通索引
CREATE INDEX index_name ON table_name (column1, column2...);
​
-- 唯一索引
CREATE UNIQUE INDEX index_name ON table_name (column);
​
-- 全文索引
CREATE FULLTEXT INDEX index_name ON table_name (column);

4.2 查看索引

复制代码
SHOW INDEX FROM table_name;

4.3 删除索引

复制代码
DROP INDEX index_name ON table_name;

5. 核心使用原则

5.1 最左前缀法则 (联合索引)

  • 规则 :查询条件必须从联合索引的最左列开始 ,并且不跳过中间的列,否则索引部分或全部失效。

  • 关键点 :执行时字段的书写顺序不影响 ,但字段必须存在

5.2 索引失效的几种常见情况

  1. 在索引列上进行运算或使用函数

  2. 字符串类型字段不加引号(发生隐式类型转换)。

  3. 模糊查询时,通配符 % 在开头 (例如 LIKE '%关键词')。

  4. 使用 OR 连接的条件 ,如果 OR 前后的字段并非都有索引。

  5. MySQL评估认为全表扫描比使用索引更快(例如查询结果是大批量数据)。

5.3 覆盖索引

  • 概念 :需要查询的所有列 ,都包含在同一个索引中。

  • 优势 :查询数据可直接从索引中获取,无需回表,极大提升性能。

  • 实践 :尽量只查询必要的字段,避免使用 SELECT *


6. 索引设计最佳实践

推荐做的事 (DO) 不建议做的事 (DON'T)
高频查询排序分组的字段上建索引 频繁增删改的字段上建过多索引
选择区分度高的列(如手机号、身份证号) 低区分度的列上建索引(如性别、状态)
使用联合索引,并遵循最左前缀法则 只为每个查询条件单独建单列索引
字符串长字段使用前缀索引 在很长的字符串上建完整索引
尽量使用覆盖索引 ,避免 SELECT * 查询返回超过表中大部分数据,索引反而慢

7. 执行计划 (EXPLAIN)

字段 重点关注项 说明
type refrangeindexALL 性能从好到差 。至少要达到 rangeref,避免 ALL (全表扫描)。
possible_keys 可能用到的索引 key 对比,看是否用了预期的索引。
key 实际使用的索引 如果为 NULL,说明没用到索引。
Extra Using indexUsing where Using index 表示使用了覆盖索引 ,是好的;Using filesortUsing temporary 是坏现象。

8. 常用命令速查

操作 命令
创建普通索引 CREATE INDEX idx_name ON table_name(column);
创建唯一索引 CREATE UNIQUE INDEX idx_name ON table_name(column);
查看索引 SHOW INDEX FROM table_name;
删除索引 DROP INDEX idx_name ON table_name;
查看执行计划 EXPLAIN SELECT ...;

9. 核心速记口诀

  • B+Tree:数据全在叶子,非叶子只存指针,叶子连成链表。

  • 聚集索引:叶子挂数据,一个表一个。

  • 二级索引:叶子挂主键,查询可能回表。

  • 覆盖索引:索引包所有,查询不回表。

  • 最左前缀:联合索引从左起,跳过中间就失效。

  • 索引失效:运算、隐式转换、%在前、OR无索引、全表更快。

相关推荐
一 乐1 小时前
在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·毕设·在线考试管理系统
玄米乌龙茶1231 小时前
数据库与缓存核心概念
数据库·缓存
IronMurphy1 小时前
MySQL拷打最后一讲!!!
mysql
無限進步D1 小时前
MySQL 子查询
数据库·mysql
骄马之死1 小时前
MyBatis SqlSession 与缓存机制详解
mysql·mybatis
Dxy12393102161 小时前
Django 模型查询中的数据库连接池配置指南
数据库·django·sqlite
Byron__1 小时前
数据库高频面试核心知识点
数据库·面试
Cloud_Shy6181 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第一章 Item 7 - 9)
开发语言·数据库·python
之歆1 小时前
Day01_ES6+ 专业指南:从基础到实战的现代JavaScript开发(上)
javascript·mysql·es6