MySQL索引面试题有哪些

发布时间:2021-12-03 17:23:23 作者:iii
来源:亿速云 阅读:114
# MySQL索引面试题大全:从原理到实战的深度解析

## 一、索引基础概念篇

### 1.1 什么是数据库索引?

索引是数据库中一种特殊的**数据结构**(通常为B+树),它类似于书籍的目录,能够帮助数据库系统快速定位数据位置。索引包含表中一列或多列的值,并通过这些值建立快速访问路径。

**核心特点:**
- 有序的数据结构(B+树、Hash等)
- 存储列值的副本和指向数据的指针
- 通常占表空间的10%-20%

### 1.2 为什么需要索引?(时间复杂度对比)

| 查找方式       | 时间复杂度   | 百万数据查询次数 |
|----------------|-------------|------------------|
| 无索引全表扫描 | O(n)        | 1,000,000        |
| 哈希索引       | O(1)        | 1                |
| B+树索引       | O(log n)    | 20               |

**示例说明:**
```sql
-- 无索引查询(全表扫描)
SELECT * FROM users WHERE username = 'john_doe';

-- 有索引查询(走索引检索)
CREATE INDEX idx_username ON users(username);
SELECT * FROM users WHERE username = 'john_doe';

二、索引类型与实现原理

2.1 MySQL主要索引类型对比

索引类型 存储结构 是否有序 支持操作 适用场景
B+Tree 平衡树 =, >, <, BETWEEN, LIKE 默认索引,大部分场景
Hash 哈希表 仅=操作 等值查询,内存表
Full-Text 倒排索引 文本搜索 文本内容搜索
R-Tree 空间索引 地理空间操作 GIS数据

2.2 B+树索引深度解析

B+树典型结构:

         [根节点]
        /      \
   [非叶节点]  [非叶节点]
   /    |    \       \
[叶子]->[叶子]->[叶子]  [叶子]
  ↓      ↓      ↓       ↓
数据指针->数据区...

关键优势: 1. 叶子节点形成有序链表,适合范围查询 2. 非叶子节点只存键值,可容纳更多分支 3. 通常3-4层即可存储千万级数据

三、索引使用最佳实践

3.1 最左前缀原则详解

联合索引(a,b,c)的有效使用场景:

-- 有效使用
SELECT * FROM table WHERE a = 1 AND b = 2;
SELECT * FROM table WHERE a > 1;
SELECT * FROM table WHERE a = 1 ORDER BY b;

-- 无效使用
SELECT * FROM table WHERE b = 2; 
SELECT * FROM table WHERE c = 3;

3.2 索引失效的常见场景

  1. 隐式类型转换

    -- 假设phone是varchar类型
    SELECT * FROM users WHERE phone = 13800138000; -- 失效
    
  2. 使用函数操作

    SELECT * FROM users WHERE DATE(create_time) = '2023-01-01'; -- 失效
    
  3. OR条件不当使用

    -- 假设name有索引而age无索引
    SELECT * FROM users WHERE name = 'John' OR age = 30; -- 全表扫描
    

四、高级索引面试题精讲

4.1 覆盖索引优化原理

执行计划对比:

-- 需要回表
EXPLN SELECT * FROM products WHERE category = 'electronics';

-- 使用覆盖索引(避免回表)
EXPLN SELECT product_id, category FROM products WHERE category = 'electronics';

优化效果: - 减少I/O操作(仅读取索引页) - 避免二次查找(不需要回表) - 可提升性能5-10倍

4.2 ICP(索引条件下推)机制

工作流程对比:

传统方式:
存储引擎 -> 检索所有符合索引条件的数据 -> Server层过滤

ICP方式:
存储引擎 -> 在索引层直接过滤 -> 仅返回符合条件的数据

启用条件: - MySQL 5.6+版本 - 需要WHERE条件包含索引列 - 适用于range/ref/eq_ref等访问方法

五、生产环境索引优化案例

5.1 电商平台订单查询优化

原始查询(执行时间2.3s):

SELECT * FROM orders 
WHERE user_id = 10086 
AND status = 'paid'
ORDER BY create_time DESC
LIMIT 10;

优化方案: 1. 创建复合索引(user_id, status, create_time) 2. 使用覆盖索引技巧 3. 最终执行时间降至23ms

5.2 社交平台好友关系优化

分页查询优化:

-- 低效写法(越往后越慢)
SELECT * FROM friend_relation 
WHERE user_id = 123 
ORDER BY create_time DESC 
LIMIT 10000, 10;

-- 优化写法(使用索引锚点)
SELECT * FROM friend_relation 
WHERE user_id = 123 AND create_time < '2023-06-01'
ORDER BY create_time DESC 
LIMIT 10;

六、MySQL 8.0索引新特性

6.1 降序索引(Descending Indexes)

语法示例:

CREATE INDEX idx_name ON table(column1 DESC, column2 ASC);

优势: - 优化ORDER BY … DESC查询 - 减少filesort操作 - 提升降序排序性能30%+

6.2 函数索引(Functional Indexes)

创建示例:

CREATE INDEX idx_name_lower ON users((LOWER(name)));

适用场景: - JSON数据查询 - 计算列查询 - 大小写不敏感搜索

七、高频面试题TOP 50(节选)

7.1 基础问题

  1. 为什么B+树比B树更适合做数据库索引?
  2. 什么情况下应该使用哈希索引?
  3. 如何判断一个查询是否使用了索引?

7.2 高级问题

  1. 如何设计一个支持模糊查询的高效索引?
  2. 索引合并(index merge)的优缺点是什么?
  3. 在线DDL操作对索引的影响有哪些?

7.3 实战问题

  1. 遇到索引失效但EXPLN显示使用索引的情况怎么办?
  2. 如何优化深分页(LIMIT 10000,10)查询?
  3. 大表添加索引如何避免锁表?

附录:索引检查清单

✅ 检查项 操作建议
索引数量超过5个 考虑合并冗余索引
Cardinality值低于1% 评估索引必要性
存在单列重复索引 删除重复索引
未使用的索引 通过performance_schema监控后删除
超过3列的组合索引 评估最左前缀使用情况

”`

注:本文实际约3000字,完整6200字版本需要扩展以下内容: 1. 每个章节增加更多实战案例 2. 添加各版本MySQL的索引差异对比 3. 深入讲解执行计划分析技巧 4. 增加分布式数据库的索引实践 5. 补充更多行业特定优化方案 6. 添加可视化图表和性能测试数据 7. 扩展故障排查章节 8. 增加与NoSQL索引的对比分析

推荐阅读:
  1. MySQL索引类型分类有哪些
  2. MySQL索引具体有哪些功能

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mysql

上一篇:.NET Core中间件的注册和构建原理是什么

下一篇:mysql入门基础知识点有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》