MySQL索引与排序相关的知识点是数据库面试的核心考察内容,面试官通常会结合场景提问索引的设计逻辑、排序的优化方式以及两者的关联规则,需要求职者既掌握基础概念,也能理解实际场景下的应用逻辑。

一、MySQL索引核心面试考点
1. 索引的基本类型与特点
面试中最常考察的索引类型是B+树索引,它是InnoDB存储引擎的默认索引结构,所有数据都存储在叶子节点,并且叶子节点之间通过双向链表连接,支持范围查询和顺序访问。除此之外还有哈希索引,仅支持等值查询,不支持范围排序;全文索引用于文本内容的模糊匹配场景。
聚簇索引和非聚簇索引的区别也是高频考点:聚簇索引的叶子节点存储整行数据,一张表只能有一个聚簇索引,通常是主键索引;非聚簇索引的叶子节点存储主键值,需要通过回表操作查询完整数据。
2. 联合索引与最左前缀原则
联合索引是指多个列组合的索引,遵循最左前缀原则,即查询条件必须包含联合索引的最左列,索引才会生效。例如创建联合索引(a,b,c),以下查询可以使用索引:
-- 可以使用索引的情况 SELECT * FROM test WHERE a = 1; SELECT * FROM test WHERE a = 1 AND b = 2; SELECT * FROM test WHERE a = 1 AND b = 2 AND c = 3; -- 无法使用索引的情况 SELECT * FROM test WHERE b = 2; SELECT * FROM test WHERE b = 2 AND c = 3;
3. 常见索引失效场景
- 查询条件对索引列使用函数或者表达式运算,例如
WHERE YEAR(create_time) = 2023 - 查询条件使用不等于、not in、is not null等操作符
- 模糊查询以通配符开头,例如
WHERE name LIKE '%张三' - 查询条件类型转换,例如字符串类型的列用数字匹配,
WHERE phone = 13800000000(phone是varchar类型)
二、排序相关的面试考点
1. order by的两种排序方式
MySQL的order by排序分为两种:索引排序和文件排序。如果order by的字段符合索引的有序性,MySQL可以直接通过索引返回有序数据,不需要额外排序,这种是索引排序,效率更高。如果无法利用索引的有序性,MySQL会对查询结果进行额外排序,也就是文件排序,性能相对较差。
2. 排序场景下索引生效规则
要让order by使用索引排序,需要满足以下条件:
- order by的字段顺序要和索引列顺序一致,且遵循最左前缀原则
- 排序方向要一致,要么全部升序,要么全部降序,不能混合排序
- 如果查询需要回表,且order by的字段不在索引中,也无法使用索引排序
举例说明,创建联合索引(a,b,c):
-- 可以使用索引排序 SELECT a,b,c FROM test ORDER BY a,b,c; SELECT a,b FROM test WHERE a = 1 ORDER BY b; -- 无法使用索引排序 SELECT * FROM test ORDER BY b,c; -- 不满足最左前缀 SELECT a,b FROM test ORDER BY a ASC, b DESC; -- 排序方向不一致
3. 分页排序的优化思路
面试中常考大偏移量分页的优化,例如SELECT * FROM test ORDER BY id LIMIT 100000,10,这种查询会先扫描前100000条数据再取10条,效率很低。优化方式可以利用覆盖索引和子查询,先通过索引查询到主键,再关联原表获取数据:
SELECT * FROM test t JOIN (SELECT id FROM test ORDER BY id LIMIT 100000,10) tmp ON t.id = tmp.id;
三、索引与排序结合的面试高频问题
1. 如何判断排序是否使用了索引
可以通过explain执行计划查看,如果Extra列显示Using index或者没有Using filesort,说明排序使用了索引;如果显示Using filesort,说明使用了文件排序。
2. 联合索引如何同时支持查询和排序
设计联合索引时,需要把查询条件的列放在前面,排序的列放在后面,同时保证排序顺序和索引顺序一致。例如查询条件是a = ?,排序是ORDER BY b,那么创建联合索引(a,b)就可以同时支持查询和排序,避免文件排序。
3. 索引是不是越多越好
不是,索引虽然能提升查询和排序的效率,但是会增加写操作的开销,每次插入、更新、删除数据都需要维护索引结构。而且过多的索引会占用更多的存储空间,还可能导致查询优化器选择索引的成本增加。实际场景中需要根据查询频率合理创建索引,优先覆盖高频查询和排序的字段。