专栏名称: Java基基
一个苦练基本功的 Java 公众号,所以取名 Java 基基
目录
相关文章推荐
丁香园  ·  这类患者降压 55~85 ... ·  昨天  
肿瘤资讯  ·  丽证一线 | 直击绝经后HR+ / ... ·  4 天前  
蒲公英Ouryao  ·  NMPA:三个中药品种被保护 ·  3 天前  
51好读  ›  专栏  ›  Java基基

面试问我SQL回表?我瞬间懵了!

Java基基  · 公众号  ·  · 2025-02-07 11:55

正文

👉 这是一个或许对你有用 的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入 芋道快速开发平台 知识星球。 下面是星球提供的部分资料:

👉 这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、 商城 、支付、工作流、大屏报表、微信公众号、 ERP CRM AI 大模型 等等功能:

  • Boot 多模块架构:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 微服务架构:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 双版本

来源:网络


最近在看关于Mysql 的相关知识,也和现在面试的小伙伴们做了一些采访,问到了一些相关的面试题,说实话,现在面试问的是越来越复杂了,很多时候也不从基础问了,直接项目走起,然后深挖项目中的一些问题,接着就是数据库中的相关问题,今天了不起来和大家一起聊一下关于 Mysql 几个经常问,但是却让人很蒙圈的面试题。

索引覆盖

在面试的时候,面试官很多会提问道优化SQL,至于怎么优化,了不起就不用再继续赘述这个问题,我们往下延伸,你了解索引覆盖么?

索引覆盖(Covering Index)或称为覆盖索引,是数据库中的一种优化手段。

当我们执行一个SQL查询时,如果只需要查询某几个字段的值,并且这几个字段的数据都已经被包含在某一个索引中(而不是全表扫描),那么数据库引擎就会直接通过这个索引来取得数据,而无需再回表查询,从而大大减少了I/O操作,提高了查询效率。

索引覆盖的优点就比如有:

  • 减少I/O次数: 因为通过覆盖索引可以直接获取数据,所以不需要再回表查询,从而减少了I/O次数。
  • 提高查询速度: 由于减少了I/O操作,查询速度自然也得到了提高。
  • 索引的选择性: 选择性是指不重复的索引值与数据表的总记录数的比值。选择性越高,通过索引筛选出的数据就越少,从而提高了查询效率。

这个我们就牵扯到回表查询了?面试官一般就会套路的继续往下问,那你知道回表操作么?

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

SQL回表

那么什么是 SQL 回表呢?

SQL回表,在MySQL数据库特别是InnoDB存储引擎中,是一个重要的概念。

SQL回表是指在使用非聚簇索引(也称为辅助索引或二级索引)进行查询时,由于非聚簇索引中只存储了索引字段的值和对应的主键(聚簇索引)键值,因此,如果需要获取非索引列的数据,则需要根据主键(聚簇索引)中的键值去查找实际的数据行。这个过程被称为“回表”。

回表的原理

  • 非聚簇索引结构: 非聚簇索引的叶子节点存储的是(索引列的值,主键的值)。
  • 查询过程: 当使用非聚簇索引进行查询时,首先通过非聚簇索引找到满足条件的主键键值。然后,根据这些主键键值,再回到聚簇索引(主键索引)中查找完整的数据行。

假设有一个用户表users,包含id(主键)、name和age三个字段,其中在name字段上建立了非聚簇索引。

执行查询 SELECT * FROM users WHERE name='Tom' 时,会发生回表。因为首先会通过name上的非聚簇索引找到满足条件的id,然后再根据这些id回到聚簇索引中查找完整的用户数据。

而查询 SELECT id, name FROM users WHERE name='Tom' 则不会回表,因为所需的数据都在非聚簇索引中可以找到。

而回表操作会增加I/O次数,从而可能影响查询性能。特别是在大表和复杂查询场景下,回表操作可能成为性能瓶颈。

为了减少回表操作,可以考虑将需要查询的字段加入到索引中,形成复合索引(也称为联合索引或覆盖索引)。这样,查询时就可以直接从索引中获取到需要的数据,而无需回表。

所以,建立索引的时候,我们要非常注意,并不是说索引不好,而是说要会加才可以。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

索引的最左匹配原则

有的时候,我们建立索引大部分都不会只是单独的一个字段,所以就有了复合索引。

索引的最左匹配原则( Leftmost Prefix Rule ) 主要是在使用复合索引(也称为多列索引或多字段索引)时的一个关键概念。这个原则指出,当使用复合索引进行查询时,查询条件应该尽可能地从索引的最左边开始匹配,这样索引才能被有效地使用。

当你基于复合索引进行查询时,查询条件必须包含索引的最左边的一列或多列,以便索引能够被有效地使用。例如,如果你有一个基于( last_name , first_name )的复合索引,以下查询可以有效地使用这个索引:

  • 查询基于last_name: SELECT * FROM employees WHERE last_name = 'Smith';
  • 查询基于last_name和first_name: SELECT * FROM employees WHERE last_name = 'Smith' AND first_name = 'John'; 但是,以下查询则不能有效地使用这个索引(因为它没有包含索引的最左边的列last_name):
  • 查询仅基于first_name: SELECT * FROM employees WHERE first_name = 'John';






请到「今天看啥」查看全文