news 2026/4/3 1:24:21

【面试题】MySQL 的覆盖索引是什么?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【面试题】MySQL 的覆盖索引是什么?

📚 MySQL 覆盖索引详解

🎯 什么是覆盖索引?

覆盖索引是指一个索引包含了查询所需的所有字段,MySQL 可以直接从索引中获取数据而无需回表查询数据行。

🔍 核心原理

/* by yours.tools - online tools website : yours.tools/zh/generatebtcwallets.html */ -- 示例表结构 CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), age INT, city VARCHAR(50), created_at DATETIME, INDEX idx_age_city_name (age, city, name) -- 复合索引 ); -- 情况1:需要回表 SELECT * FROM users WHERE age = 25; -- 虽然用到了索引,但SELECT *需要回表获取所有字段 -- 情况2:覆盖索引(无需回表) SELECT age, city, name FROM users WHERE age = 25; -- 所有需要的字段都在索引中,无需访问数据行

📊 工作原理对比

普通索引查询流程

1. 通过索引找到符合条件的行主键 2. 使用主键回表查询数据行 3. 从数据行中取出需要的字段

覆盖索引查询流程

1. 通过索引找到符合条件的索引记录 2. 直接从索引记录中取出需要的字段 3. 无需回表!

✅ 判断是否使用覆盖索引

使用EXPLAIN查看执行计划:

/* by yours.tools - online tools website : yours.tools/zh/generatebtcwallets.html */ EXPLAIN SELECT age, city FROM users WHERE age = 25;
  • Extra列显示Using index✅(使用覆盖索引)
  • Extra列显示Using index condition❌(需要回表)

💡 实际应用示例

示例1:理想的覆盖索引

-- 创建覆盖索引 CREATE INDEX idx_covering ON orders(user_id, status, amount, created_at); -- 查询:所有需要的字段都在索引中 SELECT user_id, status, amount FROM orders WHERE user_id = 100 AND status = 'paid'; -- ✅ 完全覆盖,Extra: Using index

示例2:部分覆盖

-- 假设索引:idx_name_age_city (name, age, city) SELECT name, age FROM users WHERE name LIKE '张%'; -- ✅ 覆盖索引:只查询索引包含的字段 SELECT name, age, email FROM users WHERE name LIKE '张%'; -- ❌ 需要回表:email不在索引中

🚀 覆盖索引的优势

优势说明
减少I/O索引通常比数据行小,减少磁盘读取
避免回表无需访问数据行,减少随机I/O
利用索引排序如果ORDER BY字段在索引中,可直接使用索引排序
减少内存使用索引数据更紧凑,缓冲池效率更高

性能对比示例

-- 没有覆盖索引:0.5秒 SELECT user_id, product_name FROM orders WHERE user_id = 1000; -- 添加覆盖索引后:0.02秒 CREATE INDEX idx_user_product ON orders(user_id, product_name); SELECT user_id, product_name FROM orders WHERE user_id = 1000; -- Extra: Using index

⚠️ 注意事项和限制

1. 索引列顺序很重要

-- 索引:idx_a_b_c (a, b, c) -- 覆盖索引:✅ SELECT a, b FROM users WHERE a = 1; -- 覆盖索引:✅(c在WHERE中) SELECT a, b FROM users WHERE a = 1 AND c = 2; -- 覆盖索引:❌(缺少a,索引失效) SELECT b, c FROM users WHERE b = 2;

2. TEXT/BLOB字段的限制

-- 对于TEXT/BLOB字段,即使包含在索引中也可能需要回表 CREATE INDEX idx_content ON articles(title, content(100)); SELECT title, content FROM articles WHERE title = 'MySQL'; -- 可能无法完全覆盖,取决于存储引擎和配置

3. 主键的特殊情况

-- InnoDB二级索引自动包含主键 CREATE INDEX idx_age ON users(age); -- 实际上存储的是: (age, id) -- 这些查询可以使用覆盖索引: SELECT id FROM users WHERE age = 25; -- ✅ SELECT age, id FROM users WHERE age = 25; -- ✅ SELECT age FROM users WHERE age = 25; -- ✅

🔧 优化建议

1. 设计合适的复合索引

-- 根据查询模式设计索引 -- 常见查询: SELECT user_id, order_date, total FROM orders WHERE user_id = ? AND status = 'completed' ORDER BY order_date DESC; -- 最佳索引: CREATE INDEX idx_user_status_date_total ON orders(user_id, status, order_date DESC, total); -- 完全覆盖查询需求

2. 利用覆盖索引优化分页

-- 低效的分页(需要回表) SELECT * FROM users ORDER BY created_at LIMIT 100000, 20; -- 高效的分页(使用覆盖索引) SELECT id FROM users ORDER BY created_at LIMIT 100000, 20; -- 先通过覆盖索引获取id,再关联查询 SELECT u.* FROM users u JOIN ( SELECT id FROM users ORDER BY created_at LIMIT 100000, 20 ) AS tmp ON u.id = tmp.id;

3. 监控覆盖索引使用情况

-- 查看索引使用统计 SELECT OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME, ROWS_READ, ROWS_INSERTED, ROWS_UPDATED, ROWS_DELETED FROM performance_schema.table_io_waits_summary_by_index_usage WHERE OBJECT_SCHEMA = 'your_database';

🎯 最佳实践总结

  1. 分析查询模式:找出高频查询,针对性创建覆盖索引
  2. 遵循最左前缀原则:合理安排索引列顺序
  3. 避免过度索引:权衡查询性能与写入开销
  4. 定期审查索引:使用pt-duplicate-key-checker等工具
  5. 考虑存储成本:大字段的覆盖索引可能占用大量空间

📈 性能影响示例

-- 测试覆盖索引效果 SET profiling = 1; -- 查询1:需要回表 SELECT * FROM large_table WHERE category = 'electronics'; -- 查询2:使用覆盖索引 SELECT id, category, name FROM large_table WHERE category = 'electronics'; SHOW PROFILES; -- 通常覆盖索引查询速度快2-10倍

覆盖索引是 MySQL 查询优化的重要技术,合理使用可以显著提升查询性能,特别是在处理大量数据的 OLTP 系统中。

❤️ 如果你喜欢这篇文章,请点赞支持! 👍 同时欢迎关注我的博客,获取更多精彩内容!

本文来自博客园,作者:佛祖让我来巡山,转载请注明原文链接:https://www.cnblogs.com/sun-10387834/p/19370857

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

ESP32开发新手教程:如何在Arduino IDE中上传代码

从零点亮第一颗灯:手把手教你搞定 ESP32 代码上传 你买来了人生第一块 ESP32 开发板,插上电脑,打开 Arduino IDE,信心满满地点下“上传”按钮——结果弹出一串红字:“ Failed to connect to ESP32: Timed out waitin…

作者头像 李华
网站建设 2026/3/28 7:05:34

基于Qt5(C++)外卖交易平台

C/S 架构的外卖平台引言本次作业中,我在 Qt 框架下实现了一个 C/S 架构的外卖平台软件,客户端使用到 Qt::Widgets 和 Qt::Network 模块,服务器使用到 Qt::Sql 和 Qt::Network 模块。系统的应用情景是:一个服务器实例服务多个客户端…

作者头像 李华
网站建设 2026/3/26 22:57:46

基于 SeetaFace+VS2017+Qt 的人脸识别

基于 SeetaFaceVS2017Qt 的人脸识别 1 目的 目前计算机视觉技术已经比较成熟,相关的开源项目与算法很多,可以将这些开源算法进行整合,进而做成一个小项目,以供日后学习与研究。本实验主要将利用人脸识别开源项目SeetaFace&#…

作者头像 李华
网站建设 2026/3/14 13:02:15

PPTist完全攻略:从零开始掌握在线演示工具制作技巧

PPTist完全攻略:从零开始掌握在线演示工具制作技巧 【免费下载链接】PPTist 基于 Vue3.x TypeScript 的在线演示文稿(幻灯片)应用,还原了大部分 Office PowerPoint 常用功能,实现在线PPT的编辑、演示。支持导出PPT文件…

作者头像 李华
网站建设 2026/4/1 21:45:14

电力巡检、电网安全监测、智能运维 无人机电力设备巡检电线杆鸟巢检测数据集基于深度学习YOLOV8电线杆鸟巢检测系统

无人机电力设备巡检电线杆鸟巢检测数据集 txt格式|1类电力巡检目标|1000张高清巡检图片数据集 ✅ 1000张电力巡检高清图片 ✅ txt格式标注,兼容YOLO等框架数据集规格: • 标注格式:txt类别标签及中文意思: • 0: nest …

作者头像 李华
网站建设 2026/3/27 5:25:27

14、打造愉悦用户体验的网络环境:Samba 服务器配置全攻略

打造愉悦用户体验的网络环境:Samba 服务器配置全攻略 在构建网络环境时,让用户满意是至关重要的目标。这不仅涉及到网络的稳定运行,还包括为用户提供便捷的使用体验。以下将详细介绍相关的配置和操作,帮助你打造一个高效、稳定且用户友好的网络环境。 1. 用户配置调整 1…

作者头像 李华