当前位置: 首页 > news >正文

MySQL数据库—索引

一、索引基础

1. 什么是索引?

索引是一种数据结构,它通过对表中数据按照特定规则排序,帮助数据库快速定位和查询数据,本质上类似于字典的目录:先查目录找到页码,再翻到对应页找具体内容。

2. 为什么要使用索引?

  • 核心目的提升查询效率,在海量数据下避免全表扫描。
  • ** trade-off**:查询效率提升的同时,会降低写入(INSERT/UPDATE/DELETE)效率,因为索引需要同步维护。

3. 索引的数据结构选型

不同数据结构的特性决定了其适用场景,MySQL 最终选择了B + 树作为索引的底层数据结构:

表格

数据结构时间复杂度优点缺点MySQL 支持
HASHO(1)等值查询极快不支持范围查询❌ 不默认使用
二叉搜索树O(logN)结构简单树高不可控,磁盘 I/O 次数多❌ 不使用
N 叉树O(logN)降低树高,减少 I/O节点数据冗余⚠️ 过渡方案
B + 树O(logN)支持范围查询,I/O 次数少,性能稳定结构相对复杂InnoDB 默认使用

二、B + 树与 MySQL 存储结构

1. B + 树核心特性

  • 非叶子节点:只存储索引键和子节点指针,不存储真实数据,因此单个节点可以存储更多索引,大幅降低树高。
  • 叶子节点:包含完整数据记录,且通过双向链表连接,天然支持范围查询和排序。
  • 与 B 树的区别
    1. B + 树数据只存在于叶子节点,B 树所有节点都存数据。
    2. B + 树叶子节点链表化,范围查询更高效。
    3. 相同树高下,B + 树能存储更多数据,查询路径更短。

2. MySQL 的页(Page)

  • 页是 InnoDB 与磁盘交互的最小单位,默认大小为16KB
  • 数据和索引都以页为单位存储,利用局部性原理,一次 I/O 加载一页数据到内存,提升后续查询效率。
  • 页结构:页头部(元信息)→ 数据行 → 页尾部(校验信息)。

3. B + 树在 MySQL 中的应用

  • 每个 B + 树节点就是一个,根节点、非叶子节点、叶子节点共同构成完整索引树。
  • 聚簇索引(主键索引)的叶子节点直接存储完整行数据,辅助索引的叶子节点存储主键值,需要回表查询完整数据。

三、索引分类与创建

1. 索引分类

表格

索引类型定义特点
主键索引 (PRIMARY KEY)唯一标识表中记录,非空且唯一一张表只能有一个,InnoDB 中是聚簇索引
唯一索引 (UNIQUE)列值必须唯一,允许一个 NULL业务字段有唯一性要求时使用
普通索引 (INDEX)最基础的索引类型用于提升高频查询列的查询速度
复合索引多个列共同组成的索引遵循最左前缀原则,高效支持多条件查询
覆盖索引索引包含查询所需的所有列避免回表,查询效率极高

2. 自动创建索引

  • 创建PRIMARY KEYUNIQUEFOREIGN KEY约束时,MySQL 会自动创建对应索引
  • 未指定主键时,MySQL 会自动选择一个非空唯一列作为主键,若无则生成隐藏ROW_ID作为主键。

3. 手动创建索引

3.1 主键索引

sql

-- 建表时指定 CREATE TABLE student ( id bigint PRIMARY KEY AUTO_INCREMENT, name varchar(20) NOT NULL ); -- 建表后添加 ALTER TABLE student ADD PRIMARY KEY (id);
3.2 唯一索引

sql

-- 建表时指定 CREATE TABLE student ( id bigint PRIMARY KEY AUTO_INCREMENT, name varchar(20) UNIQUE ); -- 建表后添加 ALTER TABLE student ADD UNIQUE INDEX idx_name (name);
3.3 普通 / 复合索引

sql

-- 建表时指定 CREATE TABLE student ( id bigint PRIMARY KEY AUTO_INCREMENT, name varchar(20), class_id bigint, INDEX idx_name_class (name, class_id) -- 复合索引 ); -- 建表后添加 CREATE INDEX idx_sno ON student (sno); ALTER TABLE student ADD INDEX idx_name (name);

4. 删除索引

sql

-- 删除主键索引(需先移除 AUTO_INCREMENT) ALTER TABLE student MODIFY id bigint; ALTER TABLE student DROP PRIMARY KEY; -- 删除其他索引 ALTER TABLE student DROP INDEX idx_name;

四、索引使用与优化

1. 索引生效规则

  • 最左前缀原则:复合索引会按照创建顺序排序,查询时必须包含索引的最左列才能生效。
    • 例:idx(a,b,c)支持WHERE a=?WHERE a=? AND b=?WHERE a=? AND b=? AND c=?,不支持WHERE b=?
  • 覆盖索引:查询的列都在索引中,无需回表查询,速度最快。
  • 回表查询:通过辅助索引找到主键后,再通过主键索引查询完整行数据。

2. 索引失效场景

  • 使用LIKE '%xxx'(以通配符开头)。
  • 对索引列进行函数 / 运算操作(如WHERE YEAR(create_time) = 2024)。
  • 类型隐式转换(如WHERE id = '123',id 是数字类型)。
  • 复合索引未遵循最左前缀原则。
  • 数据量过小,优化器选择全表扫描。

3. 查看与分析索引

sql

-- 查看表中所有索引 SHOW INDEX FROM student; -- 查看 SQL 执行计划,判断是否使用索引 EXPLAIN SELECT * FROM student WHERE name = '张三';
  • type字段:ref/range表示使用了索引,ALL表示全表扫描。
  • key字段:显示实际使用的索引名称。

五、最佳实践总结

  1. 选择合适的列创建索引:高频查询列、WHERE条件列、JOIN关联列。
  2. 优先使用复合索引:替代多个单列索引,减少索引数量,提升查询效率。
  3. 避免过度索引:索引越多,写入性能越差。
  4. 使用覆盖索引:将查询所需列都包含在索引中,避免回表。
  5. 定期维护索引:大数据量下,考虑使用OPTIMIZE TABLE重建索引,减少碎片。
  6. 谨慎使用SELECT *:只查询需要的列,更容易命中覆盖索引。
http://www.jsqmd.com/news/486970/

相关文章:

  • AstrBot+NapCat 打造随时随地可用的 QQ 智能机器人(1)
  • MCP工具粒度的权衡 - yi
  • 解决大模型微调的灾难性遗忘:Nova Forge 数据混合策略工程实践
  • Claude Code 费用与中转api
  • C语言指针概念详解:数组指针与二级指针的本质区别
  • 2026年高端制造视角下的气密性测试仪供应商甄选与竞争力解析 - 深度智识库
  • P8627 [蓝桥杯 2015 省 A] 饮料换购【模拟+数学】
  • 第一个Java文件!Hello,world! - Kight
  • 银河麒麟桌面操作系统 V11 来袭!硬核架构 + 全维安全
  • kubernetes知识点汇总13-18
  • 2026年气密性测试仪选购指南:趋势解析与五大优质厂商深度评测 - 深度智识库
  • 无需服务器!Windows 部署 OpenClaw,打造私人 AI助手
  • 2026年气密性检测设备厂家实力推荐高端制造质检解决方案优选指南 - 深度智识库
  • 论文排版之添加图片、表格、公式的题注
  • 文化课期间复建 OI 记录
  • 第1章 线性代数的本源:线性、结构与系统思维
  • 基于 libhv 实现多路径 WebSocket 服务器:设计与实战
  • 最近在搞AUTOSAR项目,发现生成RTE和配置协议栈这两个环节真能让人头秃。今天就带大家手搓点实战经验,顺便聊聊那些藏在XML背后的骚操作
  • 2026春季下学期第三周
  • 入门必懂:AI Agent核心概念拆解——从“是什么”到“能做什么”(2026智能体开发系列·第2篇)
  • 利用qwen 3.5-9b模型识别几何图像并转换成latex tikz代码
  • 从零配置Synplify Premier工程:手把手教你玩转FDC约束文件与安全设计(2025新版)
  • [翻译] AWS Lambda 中的按需容器加载
  • AIA | 西工大马启悦,高传强等:物理指导的激波抖振抑制翼型优化设计研究
  • 工控上位机新手避坑指南:6条血泪经验,全是现场实战总结
  • Cadence仿真MOS电容C-V曲线:从电路图到参数扫描的完整流程
  • 衡山派VE驱动测试指南:基于MPP模块的集成测试方法
  • .NET开源免费的跨平台框架 - MAUI(附学习资料)
  • “十五五”规划:新建若干所新型研究型大学
  • 用ESP32玩转多串口:UART0/1/2资源分配避坑指南(含RS485半双工冲突案例)