某滴一面:什么是回表查询、索引覆盖、最左匹配原则?
面试官:什么是回表查询、索引覆盖、最左匹配原则?聚集索引、非聚集索引的区别?
候选人:
1. 问题理解
- 回表查询:当查询需要的数据不在索引中时,数据库需要回到表中查找完整的数据,这个过程称为回表查询。
- 索引覆盖:如果查询所需的所有数据都可以通过索引直接获取,而不需要回表查询,这种情况称为索引覆盖。
- 最左匹配原则:在使用复合索引时,查询条件必须从索引的最左边的列开始匹配,才能有效利用索引。
- 聚集索引与非聚集索引:聚集索引是按照索引顺序存储数据的索引,而非聚集索引是单独存储索引信息,数据存储在其他位置。
2. 回表查询
2.1 通俗解释
- 假设你有一个图书馆,书架上的书是按照作者名字排序的(这就是索引)。如果你要找一本“鲁迅”写的书,你可以直接在“鲁迅”的区域找到书(这就是索引查询)。但如果书架上只记录了书名和作者,而你要找的是书的出版年份,你就需要找到书后再翻开书查看出版年份(这就是回表查询)。
2.2 示例 假设有一个表users,包含字段id、name、age,并且有一个索引idx_name在name字段上。
sql复制
SELECT id, name FROM users WHERE name = 'John';
这个查询可以直接通过索引idx_name找到id和name,不需要回表查询。
但如果查询是:
sql复制
SELECT id, name, age FROM users WHERE name = 'John';
那么在通过索引找到name为John的记录后,还需要回到表中查找age字段,这就是回表查询。
3. 索引覆盖
3.1 通俗解释
- 索引覆盖就是查询所需的所有信息都可以在索引中直接找到,不需要回表查询。就像你在图书馆可以直接通过作者名字找到书名,而不需要翻开书查看其他信息。
3.2 示例 继续上面的例子,如果查询是:
sql复制
SELECT name FROM users WHERE name = 'John';
这个查询只需要通过索引idx_name就可以找到所有需要的信息,这就是索引覆盖。
4. 最左匹配原则
4.1 通俗解释
- 最左匹配原则是指在复合索引中,查询条件必须从索引的最左边的列开始匹配,才能有效利用索引。就像你有一个书架,书是按照作者名字和书名排序的,你必须先按作者名字查找,才能按书名查找。
4.2 示例 假设有一个表users,包含字段id、name、age,并且有一个复合索引idx_name_age在name和age字段上。
sql复制
SELECT * FROM users WHERE name = 'John' AND age = 25;
这个查询可以有效利用复合索引idx_name_age,因为查询条件从索引的最左边的列name开始匹配。
但如果查询是:
sql复制
SELECT * FROM users WHERE age = 25;
这个查询无法有效利用复合索引idx_name_age,因为查询条件没有从索引的最左边的列name开始匹配。
5. 聚集索引与非聚集索引的区别
5.1 聚集索引
- 定义:聚集索引是按照索引顺序存储数据的索引。在MySQL的InnoDB存储引擎中,表数据本身是按照主键索引存储的,主键索引就是聚集索引。
- 特点:
- 数据存储顺序与索引顺序一致。
- 每个表只能有一个聚集索引。
- 查询效率高,因为数据存储在一起。
5.2 非聚集索引
- 定义:非聚集索引是单独存储索引信息,数据存储在其他位置。在MySQL中,除了主键索引外的其他索引都是非聚集索引。
- 特点:
- 索引和数据分开存储。
- 可以有多个非聚集索引。
- 查询时可能需要回表查询。
5.3 示例 假设有一个表users,包含字段id(主键)、name、age,并且有一个非聚集索引idx_name在name字段上。
- 聚集索引查询:
- sql复制
- SELECT * FROM users WHERE id = 1;
- 这个查询直接通过主键索引(聚集索引)找到数据,效率很高。
- 非聚集索引查询:
- sql复制
- SELECT * FROM users WHERE name = 'John';
- 这个查询通过非聚集索引idx_name找到name为John的记录,但需要回表查询其他字段。
6. 总结
- 回表查询:查询需要的数据不在索引中时,需要回到表中查找完整的数据。
- 索引覆盖:查询所需的所有数据都可以通过索引直接获取,不需要回表查询。
- 最左匹配原则:查询条件必须从索引的最左边的列开始匹配,才能有效利用索引。
- 聚集索引与非聚集索引:聚集索引是按照索引顺序存储数据的索引,非聚集索引是单独存储索引信息,数据存储在其他位置。