MySQL基础教程之索引的定义与作用

 更新时间:2026年02月09日 09:50:56   作者:ttthe_MOon  
索引是数据库中用于提高数据检索效率的一种数据结构,它类似于书籍的目录,允许用户快速定位到所需数据的位置,而无需扫描整个数据表,这篇文章主要介绍了MySQL基础教程之索引定义与作用的相关资料,需要的朋友可以参考下

一、索引的定义与核心作用

1. 定义

索引是 MySQL 中用于优化查询效率的数据结构,类比书籍的“目录”,无需遍历全表即可快速定位数据位置。

2. 核心作用

提升查询速度:避免全表扫描(Full Table Scan),减少磁盘 I/O 和 CPU 资源消耗;

优化排序/分组:支持 GROUP BY ORDER BY 操作快速完成(无需额外排序);

加速表连接:优化 JOIN 操作中关联字段的匹配效率。

二、索引的工作逻辑

当执行 SELECT 查询时,MySQL 执行流程如下:

  1. 解析查询语句,识别查询的表和字段;

  2. 检查该字段是否存在索引:

    若有索引:遍历索引表(数据结构如 B+ 树),快速定位到数据记录行的物理地址,直接读取数据;

    若无索引:执行全表扫描,逐行遍历表中所有数据,匹配目标结果(效率低、资源消耗高)。

三、索引的副作用(不可忽视)

索引并非“越多越好”,存在以下代价:

  1. 占用额外磁盘空间:索引表独立于数据表格,会消耗磁盘存储(如大表的组合索引可能占用大量空间);

  2. 增加更新开销:修改(INSERT/UPDATE/DELETE)含索引的表时,需同步更新对应的索引表(如修改主键值时,主键索引需重新排序);

  3. 不合理索引降低效率:如在低选择性字段创建索引,可能导致 MySQL 放弃使用索引,直接全表扫描。

四、索引的创建依据(适合/不适合场景)

1. 适合创建索引的场景

主键和外键:默认创建主键索引,外键常用于表连接,必须建索引;

大数据量表:记录数超过 300 行的表,全表扫描代价过高;

高频查询字段:WHERE 子句中频繁出现的字段(如用户查询、筛选条件);

连接/排序/分组字段:JOIN 关联字段、GROUP BY/ORDER BY 操作的字段;

高选择性字段:字段不同值占比高(如身份证号、手机号,选择性接近 1),索引过滤效果好;

小字段:优先在 INT、VARCHAR(短) 等小字段建索引(长文本、BLOB 等大字段索引开销极高)。

2. 不适合创建索引的场景

低选择性字段:如性别(男/女)、布尔值(0/1),索引过滤效果差,不如全表扫描;

更新频繁的字段:如订单状态(高频更新),索引同步开销会抵消查询收益;

小表(<300 行):全表扫描速度快,索引带来的开销大于收益;

高频全表查询字段:若查询常使用 SELECT * 且无过滤条件,索引无效。

五、MySQL 常见索引类型及特点

索引类型核心特点适用场景
主键索引(PRIMARY KEY)唯一、非空,一张表仅一个,默认自动创建,底层为聚簇索引(数据与索引存储在一起)表的唯一标识(如用户 ID、订单 ID)
唯一索引(UNIQUE KEY)字段值唯一(允许 NULL 值,仅一个 NULL),避免重复数据用户名、邮箱等需唯一约束的字段
组合索引(复合索引)基于多个字段创建(如 idx_name_age (name, age)),遵循“最左前缀原则”多字段联合查询(如 WHERE name='xxx' AND age=xx
全文索引(FULLTEXT)支持长文本模糊匹配(如文章内容、评论),不支持精确查询博客、新闻等文本内容的关键词搜索

补充:组合索引“最左前缀原则”

示例:创建组合索引 idx_a_b_c (a, b, c),仅支持以下查询场景命中索引:

  • WHERE a=?(左前缀匹配)

  • WHERE a=? AND b=?(连续前缀匹配)

  • WHERE a=? AND b=? AND c=?(全匹配)

不命中场景:WHERE b=? WHERE a=? AND c=?(跳过中间字段)。

六、索引与慢查询的关联

1. 慢查询与索引的关系

慢查询定义:默认情况下,执行时间超过 2 秒的 SELECT 语句(可通过 long_query_time 配置修改);

核心原因之一:查询未使用索引(全表扫描),导致耗时过长;

配置日志记录:在 /etc/my.cnf 中开启以下配置,记录未使用索引的慢查询:

[mysqld]
slow_query_log = 1  # 开启慢查询日志
slow_query_log_file = /var/lib/mysql/mysql-slow.log  # 日志存储路径
long_query_time = 2  # 慢查询阈值(单位:秒)
log_queries_not_using_indexes = 1  # 记录未使用索引的 SQL

配置后需重启 MySQL 服务生效。

2. 验证索引有效性:EXPLAIN工具

作用:分析 SQL 执行计划,查看是否使用索引、索引类型、扫描行数等;

用法:在查询语句前加 EXPLAIN,示例:

EXPLAIN SELECT * FROM user WHERE id=1;

关键字段解读:

  • type:索引使用类型(ALL 表示全表扫描,ref/range/eq_ref 表示使用索引);

  • key:实际使用的索引名称(NULL 表示未使用索引);

  • rows:预估扫描的行数(值越小,效率越高)。

七、索引底层与优化技巧

1. 索引底层数据结构(MySQL 默认)

采用 B+ 树 结构,优势:

叶子节点有序排列,支持范围查询(如 BETWEEN IN);

叶子节点存储数据地址(非聚簇索引)或数据本身(聚簇索引),查询效率稳定;

树高度低(百万级数据仅需 3-4 层),磁盘 I/O 次数少。

2. 聚簇索引 vs 非聚簇索引

聚簇索引:索引与数据存储在一起(如主键索引),查询无需“回表”,效率最高;

非聚簇索引:索引与数据分离,叶子节点存储主键值,查询需通过主键值二次查找数据(回表),效率略低。

3. 索引失效的常见场景(避坑!)

索引字段使用函数/运算:WHERE SUBSTR(name,1,2)='张'(无法命中 name 索引);

模糊查询以 % 开头:WHERE name LIKE '%三'(全模糊 %三% 也失效);

OR 条件中部分字段无索引:WHERE id=1 OR age=20(若 age 无索引,整个查询可能全表扫描);

隐式类型转换:WHERE phone='123456'phone 为 INT 类型,字符串与数字转换导致索引失效);

联合查询中违背最左前缀原则(见组合索引部分)。

4. 索引优化技巧

覆盖索引:查询字段仅包含索引列(如 SELECT id, name FROM user WHERE id=1id 为主键索引),避免回表;

定期维护索引:删除冗余索引(如已存在 idx_a_b,无需再建 idx_a)、优化碎片索引(OPTIMIZE TABLE 表名);

避免过度索引:一张表索引数量建议不超过 5 个,过多索引会导致更新变慢。

八、核心小结

  1. 索引核心价值:加速查询,减少全表扫描开销;

  2. 创建原则:“高频查询、高选择性、小字段”优先,避开“更新频繁、低选择性”字段;

  3. 验证工具:用 EXPLAIN 检测索引是否生效,结合慢查询日志优化索引;

  4. 平衡取舍:索引并非越多越好,需权衡查询效率与更新开销。

到此这篇关于MySQL基础教程之索引定义与作用的文章就介绍到这了,更多相关MySQL索引定义与作用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL日志分析软件mysqlsla的安装和使用教程

    MySQL日志分析软件mysqlsla的安装和使用教程

    这篇文章主要介绍了MySQL日志分析软件mysqlsla的安装和使用教程,文中以Linux系统作为环境进行示例,需要的朋友可以参考下
    2015-11-11
  • SQL UNION运算符及其应用场景深入探究

    SQL UNION运算符及其应用场景深入探究

    这篇文章主要为大家介绍了SQL UNION运算符及其应用场景示例深入探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • MySQL 中的 CAST 函数详解及常见用法

    MySQL 中的 CAST 函数详解及常见用法

    CAST 函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL 中的 CAST 函数,感兴趣的朋友一起看看吧
    2025-07-07
  • 详解MySQL中存储函数创建与触发器设置

    详解MySQL中存储函数创建与触发器设置

    这篇文章主要为大家详细介绍了MySQL中存储函数的创建与触发器的设置,文中的示例代码讲解详细,具有一定的学习价值,需要的可以参考一下
    2022-08-08
  • MySQL千万级大数据SQL查询优化知识点总结

    MySQL千万级大数据SQL查询优化知识点总结

    在本篇文章里小编给大家整理的是一篇关于MySQL千万级大数据SQL查询优化知识点总结内容,有需要的朋友们可以学习参考下。
    2019-12-12
  • 详解MySQL事务的ACID如何实现

    详解MySQL事务的ACID如何实现

    事务(Transaction)是并发控制的基本单位,所谓的事务呢,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位,本文给大家详细介绍了MySQL事务的ACID如何实现,需要的朋友可以参考下
    2023-10-10
  • Linux下mysql 8.0.15 安装配置图文教程以及修改密码

    Linux下mysql 8.0.15 安装配置图文教程以及修改密码

    这篇文章主要为大家详细介绍了Linux下mysql 8.0.15安装配置图文教程以及修改密码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • Mysql中幻读的概念以及如何解决

    Mysql中幻读的概念以及如何解决

    这篇文章主要介绍了Mysql中幻读的概念以及如何解决,幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行,需要的朋友可以参考下
    2023-05-05
  • 在MySQL现有表中添加自增ID的方法步骤

    在MySQL现有表中添加自增ID的方法步骤

    当在MySQL数据库中,自增ID是一种常见的主键类型,它为表中的每一行分配唯一的标识符,在某些情况下,我们可能需要在现有的MySQL表中添加自增ID,以便更好地管理和索引数据,在本文中,我们将讨论如何在MySQL现有表中添加自增ID,并介绍相关的步骤和案例
    2023-09-09
  • Mysql8创建用户以及赋权操作过程

    Mysql8创建用户以及赋权操作过程

    文章详细介绍了MySQL 8中创建用户、赋权及权限管理的操作步骤,包括创建不限制IP的用户、赋权数据库所有表、使用WITH GRANT OPTION传递权限、刷新权限、撤销权限、删除用户等,同时强调了权限修改后需刷新及注意权限继承关系
    2025-07-07

最新评论