news 2026/4/23 12:44:57

MySQL索引

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL索引

MySQL索引详解

一、索引是什么?

索引是数据库中的一种数据结构,类似于书籍的目录,它可以帮助数据库快速定位和访问表中的数据,而不需要扫描整个表。

二、MySQL索引分类

1.按数据结构分类

索引类型存储引擎特点适用场景
B+Tree索引InnoDB、MyISAM默认索引,平衡树结构范围查询、排序、等值查询
Hash索引Memory/Heap哈希表结构,O(1)查找等值查询(不支持范围查询)
Full-Text索引InnoDB、MyISAM全文搜索文本字段的模糊搜索
R-Tree索引MyISAM空间数据索引GIS地理数据

2.按逻辑功能分类

主键索引 (Primary Key)
CREATETABLEusers(idINTPRIMARYKEY,-- 主键索引nameVARCHAR(50));
  • 每张表只能有一个
  • 不允许NULL值
  • 自动创建聚簇索引(InnoDB)
唯一索引 (Unique Index)
CREATEUNIQUEINDEXidx_emailONusers(email);
  • 确保列值唯一
  • 允许NULL值(但只能有一个NULL)
  • 可以有多个
普通索引 (Normal Index)
CREATEINDEXidx_nameONusers(name);
  • 最基本的索引类型
  • 仅用于加速查询
全文索引 (Full-Text Index)
CREATEFULLTEXTINDEXidx_contentONarticles(content);
  • 用于全文搜索
  • 支持MATCH AGAINST语法
组合索引 (Composite Index)
CREATEINDEXidx_name_ageONusers(name,age);
  • 多列组合的索引
  • 最左前缀原则
空间索引 (Spatial Index)
CREATESPATIALINDEXidx_locationONplaces(location);
  • 用于地理空间数据

3.按物理存储分类

聚簇索引 (Clustered Index)
  • InnoDB中主键就是聚簇索引
  • 数据行和索引存储在一起
  • 一个表只有一个
非聚簇索引 (Non-Clustered Index)
  • 索引和数据分开存储
  • MyISAM默认都是非聚簇索引
  • InnoDB的二级索引

三、常用索引类型

最常用的索引:

  1. B+Tree索引(95%以上场景)
  2. 组合索引(优化多条件查询)
  3. 唯一索引(保证数据唯一性)
  4. 主键索引(每张表必须有)

四、索引生效场景(什么时候有效)

1. 全值匹配

-- 索引 idx_name_age(name, age)SELECT*FROMusersWHEREname='张三'ANDage=25;-- ✅ 生效

2. 最左前缀匹配

-- 索引 idx_name_age_city(name, age, city)SELECT*FROMusersWHEREname='张三';-- ✅ 生效SELECT*FROMusersWHEREname='张三'ANDage=25;-- ✅ 生效SELECT*FROMusersWHEREage=25;-- ❌ 不生效(跳过了name)

3. 范围查询(部分生效)

-- 索引 idx_name_age(name, age)SELECT*FROMusersWHEREname='张三'ANDage>20;-- ✅ 生效SELECT*FROMusersWHEREname>'张三';-- ✅ 生效

4. 覆盖索引

-- 索引 idx_name_age(name, age)SELECTname,ageFROMusersWHEREname='张三';-- ✅ 生效(不需要回表)

5. 排序操作

-- 索引 idx_name_age(name, age)SELECT*FROMusersORDERBYname,age;-- ✅ 生效SELECT*FROMusersORDERBYnameASC,ageDESC;-- ❌ 不生效(混合排序)

6. 分组操作

-- 索引 idx_name_age(name, age)SELECTname,COUNT(*)FROMusersGROUPBYname;-- ✅ 生效

五、索引失效场景(什么时候无效)

1. 违反最左前缀原则

-- 索引 idx_name_age(name, age)SELECT*FROMusersWHEREage=25;-- ❌ 不生效SELECT*FROMusersWHEREage=25ANDname='张三';-- ✅ 生效(优化器会调整顺序)

2. 在索引列上运算或函数

-- 索引 idx_name(name)SELECT*FROMusersWHERELEFT(name,1)='张';-- ❌ 不生效SELECT*FROMusersWHEREYEAR(create_time)=2024;-- ❌ 不生效

3. 使用不等于(!=, <>)

SELECT*FROMusersWHEREname!='张三';-- ❌ 不生效(全表扫描更优)

4. 使用IS NULL/IS NOT NULL(特殊情况)

SELECT*FROMusersWHEREnameISNULL;-- ✅ 可能生效SELECT*FROMusersWHEREnameISNOTNULL;-- ❌ 通常不生效

5. LIKE以通配符开头

SELECT*FROMusersWHEREnameLIKE'%张三%';-- ❌ 不生效SELECT*FROMusersWHEREnameLIKE'张三%';-- ✅ 生效

6. 类型转换

-- 假设phone是varchar类型,索引 idx_phone(phone)SELECT*FROMusersWHEREphone=13800138000;-- ❌ 不生效(隐式类型转换)SELECT*FROMusersWHEREphone='13800138000';-- ✅ 生效

7. OR条件部分无索引

-- name有索引,age无索引SELECT*FROMusersWHEREname='张三'ORage=25;-- ❌ 不生效

8. 数据量小时

-- 表只有100行数据SELECT*FROMsmall_tableWHEREname='test';-- ❌ 可能不生效(全表扫描更快)

9. 统计信息不准确

-- 当索引统计信息过时,优化器可能选择全表扫描ANALYZETABLEusers;-- 更新统计信息

六、索引设计最佳实践

创建索引的黄金法则:

-- 1. 选择性高的列建索引CREATEINDEXidx_emailONusers(email);-- email唯一性高-- 2. 常用查询条件组合建索引CREATEINDEXidx_queryONorders(user_id,status,create_time);-- 3. 覆盖索引设计CREATEINDEXidx_coveringONusers(name,age,email);-- 查询:SELECT name, age, email FROM users WHERE name = '张三';

索引使用建议:

  1. 不要过度索引:每个索引都有维护成本
  2. 更新频繁的列:谨慎建索引
  3. 小表不建议建索引
  4. 避免冗余索引
  5. 定期分析索引使用情况
-- 查看索引使用情况SHOWINDEXFROMtable_name;-- 查看未使用的索引SELECT*FROMsys.schema_unused_indexes;

七、性能诊断工具

1. EXPLAIN分析

EXPLAINSELECT*FROMusersWHEREname='张三';

2. 查看索引统计

-- 查看索引区分度SELECTINDEX_NAME,CARDINALITY,TABLE_ROWS,ROUND(CARDINALITY/TABLE_ROWS*100,2)asselectivityFROMinformation_schema.STATISTICSWHERETABLE_NAME='users';

3. 慢查询日志

-- 开启慢查询SETGLOBALslow_query_log=ON;SETGLOBALlong_query_time=1;

八、常见问题排查

索引失效排查步骤:

  1. 使用EXPLAIN分析执行计划
  2. 检查WHERE条件是否符合最左前缀
  3. 检查是否有类型转换
  4. 检查是否使用函数或计算
  5. 检查统计信息是否准确
  6. 检查数据量是否太小

索引优化示例:

-- 问题查询SELECT*FROMordersWHEREDATE(create_time)='2024-01-01'-- ❌ 索引失效ANDstatus=1;-- 优化后SELECT*FROMordersWHEREcreate_time>='2024-01-01'ANDcreate_time<'2024-01-02'-- ✅ 索引生效ANDstatus=1;-- 创建合适索引CREATEINDEXidx_time_statusONorders(create_time,status);

记住原则:索引不是越多越好,合适的索引才是最好的。定期审查和优化索引是DBA的重要工作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 15:59:19

动手试了FSMN-VAD,长音频自动分割真实体验分享

动手试了FSMN-VAD&#xff0c;长音频自动分割真实体验分享 最近在处理一批会议录音和课程音频&#xff0c;动辄一两个小时&#xff0c;手动剪掉中间的长时间停顿、翻页声、咳嗽声&#xff0c;光是听就要花半天。听说达摩院开源的FSMN-VAD模型在中文语音端点检测上表现很稳&…

作者头像 李华
网站建设 2026/4/23 11:12:22

语音识别应用场景盘点:这款镜像覆盖80%日常需求

语音识别应用场景盘点&#xff1a;这款镜像覆盖80%日常需求 你有没有过这样的经历&#xff1a;会议录音堆了十几条&#xff0c;却没时间逐条听写&#xff1b;采访素材录了一小时&#xff0c;整理文字花了三天&#xff1b;客户语音留言太多&#xff0c;漏掉关键信息被追着问&am…

作者头像 李华
网站建设 2026/4/22 18:43:12

超详细版蜂鸣器电路设计:包含原理图与参数计算

以下是对您提供的博文《超详细版蜂鸣器电路设计&#xff1a;原理、参数计算与工程实践深度解析》的 全面润色与专业升级版本 。本次优化严格遵循您的全部要求&#xff1a; ✅ 彻底去除AI痕迹&#xff0c;语言更贴近资深硬件工程师口吻 ✅ 所有标题重构为自然、有力、具象的…

作者头像 李华
网站建设 2026/4/23 11:15:42

verl边缘计算部署:端侧RL训练可行性分析

verl边缘计算部署&#xff1a;端侧RL训练可行性分析 1. verl是什么&#xff1a;为大模型后训练量身打造的强化学习框架 verl是一个灵活、高效、面向生产环境的强化学习&#xff08;RL&#xff09;训练框架&#xff0c;专为大型语言模型&#xff08;LLMs&#xff09;的后训练阶…

作者头像 李华
网站建设 2026/4/23 11:13:28

大模型落地实战:Qwen3-1.7B在内容生成中的应用案例

大模型落地实战&#xff1a;Qwen3-1.7B在内容生成中的应用案例 1. 为什么是Qwen3-1.7B&#xff1f;轻量、高效、开箱即用的内容生成新选择 很多人一听到“大模型”&#xff0c;第一反应是显存吃紧、部署复杂、响应慢。但如果你只需要一个能稳定写文案、润色报告、生成产品描述…

作者头像 李华
网站建设 2026/4/23 12:37:48

Z-Image-Turbo生成多样性差?guidance_scale参数优化教程

Z-Image-Turbo生成多样性差&#xff1f;guidance_scale参数优化教程 1. 为什么你总生成“差不多”的图&#xff1f; 你是不是也遇到过这种情况&#xff1a;输入了完全不同的提示词&#xff0c;比如“一只穿西装的柴犬”和“一只在太空站里泡咖啡的柴犬”&#xff0c;结果生成…

作者头像 李华