MySQL 中的回表是什么?MySQL 中使用索引一定有效吗?如何排查索引效果?在 MySQL 中建索引时需要注意哪些事项?

news2025/2/22 6:55:59

MySQL 中的回表是什么?

1. 背景知识

MySQL 中有两种常见的索引:

  • 主键索引(Primary Key Index) :唯一标识表中的每一行数据,使用 B+ 树结构存储。主键索引的叶子节点存储的是完整的行数据。
  • 非主键索引(Secondary Index) :包括普通索引、唯一索引等,也是使用 B+ 树结构存储。非主键索引的叶子节点存储的是主键值(或者唯一标识行的数据)和一些其他信息(如聚簇索引的指针)。

2. 什么是回表

当查询语句使用非主键索引进行查找时,非主键索引的叶子节点只包含主键值(或者唯一标识行的数据)和一些其他信息,并不包含完整的行数据。为了获取完整的行数据,MySQL 需要根据非主键索引中的主键值再去主键索引中查找对应的行数据,这个过程就叫做回表。

3. 示例说明

假设有一个学生表(student):

student_idnameageclass_id
1Alice20101
2Bob21102
3Carol20103

该表有主键索引(student_id)和一个非主键索引(class_id)。

如果执行以下查询语句:

SELECT * FROM student WHERE class_id = 101;

查询过程如下 :

  • MySQL 首先使用非主键索引(class_id)查找满足条件(class_id = 101)的记录,在非主键索引的叶子节点中找到对应的主键值(student_id = 1)。
  • 然后,MySQL 根据主键值(student_id = 1)去主键索引中查找对应的完整行数据,这就是回表的过程。

4. 回表的影响

  • 优点 :在某些情况下,使用非主键索引可以快速定位到满足条件的记录,然后再通过回表获取完整的行数据,这样可以提高查询效率。
  • 缺点 :回表会增加一次 IO 操作(从非主键索引到主键索引的查找),如果查询语句中只需要部分列的数据,而这些数据已经包含在非主键索引中,那么回表就会造成不必要的性能开销。

5. 避免回表的方法

  • 使用覆盖索引 :如果查询语句中需要的列都包含在非主键索引中,那么就可以避免回表。覆盖索引是指索引包含了查询语句中需要的所有列。
  • 优化查询语句 :尽量避免使用 SELECT * ,只查询需要的列,这样可以减少回表的次数。

MySQL 中使用索引一定有效吗?如何排查索引效果?

MySQL 中使用索引不一定有效

在 MySQL 中,索引的使用并不总是能提升查询性能,以下是一些可能导致索引无效或不被使用的情况:

索引选择性差 :如果索引列的数据选择性较低,即索引列的不同值的数量与表中总行数的比值接近 0,例如性别列只有 “男” 和 “女” 两个值,此时索引可能不会被使用,因为通过索引查找并不能显著减少需要扫描的行数,MySQL 可能会选择全表扫描。

数据表过小 :对于数据量很小的表,全表扫描的开销可能比使用索引的开销更低,因此 MySQL 可能不会使用索引。

索引维护成本高 :在大量插入、更新、删除操作的场景下,索引的维护(如重建索引)会成为负担,影响性能,此时索引可能不会被使用。

查询优化器决策 :MySQL 的查询优化器会根据统计信息选择查询执行计划,有时它可能认为全表扫描比使用索引更高效,从而不使用索引。

索引未覆盖查询 :如果查询需要的数据列没有被索引完全覆盖,MySQL 仍然需要回表访问原始数据表来获取缺失的列,这可能会抵消索引带来的性能提升。

范围查询 :使用了范围查询(如 BETWEEN><LIKE 等)时,索引会被部分使用,通常只能利用范围查询前的字段索引。

对索引列使用函数或表达式 :在查询中对索引列使用了函数(如 YEAR(date_column))或进行表达式计算时,索引可能会失效,因为计算后的值与存储的索引值不匹配。

隐式类型转换 :在查询中,如果传入的查询条件数据类型与索引列的数据类型不同,MySQL 可能会进行隐式类型转换,导致索引失效 。

使用 OR 操作符 :当 WHERE 子句中包含 OR 时,索引可能失效,尤其是当 OR 左右两边的条件索引不同或包含非索引列时 。

排查索引效果的方法

使用 EXPLAIN 命令分析查询计划EXPLAIN 命令可以显示 MySQL 执行查询时选择的执行计划,帮助判断是否使用了索引以及索引的使用情况。关键字段包括 key(显示使用的索引)、type(连接类型,如 ALL 表示全表扫描,range 表示范围扫描,ref 表示索引查找)、extra(提供有关查询执行的其他信息,如是否使用了索引覆盖)。

查看慢查询日志 :通过启用慢查询日志,可以查看哪些查询可能因为没有使用索引而执行缓慢。配置慢查询日志的相关参数包括 slow_query_log(设置为 1 启用慢查询日志)、slow_query_log_file(指定慢查询日志文件路径)、long_query_time(设置记录执行时间超过该值的查询)。

使用 SHOW WARNINGS 排查索引失效原因 :如果查询没有使用索引,MySQL 会通过 SHOW WARNINGS 显示相关警告信息,指示索引未能使用的原因。

查看索引统计信息 :通过 SHOW INDEX FROM your_table; 查看表的索引信息,并结合 SHOW TABLE STATUS 了解表的大致统计信息,如行数、平均行长度等,确保统计信息是最新的 。

分析数据分布 :了解索引列的数据分布情况,如果数据分布极不均匀(如大量重复值),可能需要重新考虑索引策略或调整查询逻辑。

使用性能分析工具 :利用 MySQL 的 Performance Schema、慢查询日志或第三方性能分析工具(如 Percona Toolkit 的 pt-query-digest),分析哪些查询是性能瓶颈,并针对性地优化。

在 MySQL 中建索引时需要注意哪些事项?

1. 索引的必要性

  • 选择性(Selectivity) :索引列的选择性越高,查询的性能提升越明显。选择性是指不重复的索引值(基数)与表中记录总数的比值。例如,一个学生表中的 “性别” 列,其基数为 2(男、女),选择性较低。 如果表中有 1000 条记录,那么性别列的选择性为 2/1000=0.002。在这种情况下,MySQL 可能会认为使用索引的代价(如随机磁盘 I/O)比全表扫描更高,从而放弃使用索引。

2. 数据类型的隐式转换

  • 例如,当一个字符串列(如 charvarchar)上有索引,而查询中使用的是数字作为条件值时,MySQL 可能会进行隐式类型转换,导致索引失效。例如:
CREATE TABLE user (
    id INT PRIMARY KEY,
    name CHAR(50) NOT NULL,
    INDEX(name)
);

执行以下查询时,会由于索引列 name 的类型是 CHAR,而查询条件中的 name = 123 使用的是整数类型,MySQL 会将整个表中的 name 字段转换为整型进行比较,导致索引失效:

SELECT * FROM user WHERE name = 123;

3. 索引列的基数

  • 索引列的基数(即不同值的数量)越大,索引的选择性越高。例如,一个表中的 “order_date” 列,其基数是日期的数量,如果日期范围很广,基数就大,选择性就高。相反,如果一个列的基数很低(如性别列的男、女),索引的效率会较低,MySQL 可能不会选择使用索引。

4. 覆盖索引

  • 定义 :覆盖索引是指查询需要的所有数据列都包含在索引中,MySQL 可以直接从索引中获取数据,而不需要回表查询。例如,SELECT name, age FROM user WHERE class_id = 101;,如果非主键索引 class_id 上同时包含了 nameage 列的信息,那么可以直接使用覆盖索引获取数据。
  • 优点 :覆盖索引可以减少磁盘 I/O 和数据访问时间,提高查询性能。
  • 局限性 :如果查询需要的数据列不在索引中,MySQL 仍然需要回表获取数据,此时覆盖索引就无法发挥作用。

5. 复合索引的列顺序

  • 最左前缀法则 :复合索引的列顺序很重要。MySQL 会按照索引列的顺序从左到右依次匹配查询条件。例如,复合索引 (col_a, col_b, col_c),查询条件可以是 col_acol_a, col_bcol_a, col_b, col_c,但不能是 col_bcol_b, col_c,否则无法使用索引。
  • 查询条件的优化 :如果查询条件中经常需要使用 col_bcol_c,那么复合索引的顺序可能应该调整为 (col_b, col_c)(col_b, col_c, col_a),但这需要根据实际的查询需求和数据分布情况权衡。

6. 范围查询

  • 在使用复合索引时,如果查询条件中包含范围查询(如 <><=>=BETWEENLIKE 等),MySQL 只能利用范围查询前的索引列。例如,对于复合索引 (col_a, col_b, col_c),查询条件 WHERE col_a = 10 AND col_b > 20 会利用 col_acol_b 的索引;如果查询条件是 WHERE col_b > 20 AND col_c = 30,则只能利用 col_b 的索引,而无法利用 col_c 的索引。

7. 数据分布

  • 索引列的数据分布均匀时,索引的效率更高。如果数据分布极不均匀(如倾斜分布),MySQL 可能会优先选择数据较少的部分进行扫描,从而影响查询性能。例如,一个用户的登录时间列中,大部分数据集中在某一时间段,索引的效率就会受到影响。

8. 索引维护成本

  • 索引需要占用额外的存储空间。对于表来说,每个索引都会占用一部分磁盘空间。同时,索引会增加插入、更新和删除操作的开销,因为需要维护索引结构。例如,当向表中插入一条数据时,MySQL 不仅需要更新数据表,还需要更新相关的索引,这会增加写操作的时间。

9. 存储引擎的限制

  • 不同的存储引擎对索引的处理方式不同。例如,InnoDB 存储引擎使用聚簇索引(即主键索引),表的数据按照主键顺序存储,而 MyISAM 存储引擎则是非聚簇索引,表的数据和索引是分开存储的。

10. 查询条件与索引

  • 确保查询条件中的列没有进行函数运算或其他可能导致索引失效的操作。例如,查询条件 WHERE YEAR(date_col) = 2023; 中使用了函数 YEAR(),MySQL 无法直接使用 date_col 的索引。
  • 如果需要对索引列进行函数运算,可以考虑在函数基础上创建索引(如函数索引),或者重新设计查询逻辑以避免使用函数。

11. 索引与查询优化器

  • MySQL 的查询优化器会根据统计信息(如数据分布、表大小等)选择查询执行计划。有时候,即使存在索引,查询优化器也可能选择不使用索引(如认为全表扫描更快)。因此,需要通过 EXPLAIN 命令分析查询计划,确保索引被正确使用。

12. 索引前缀

  • 如果对字符串列(如 varcharchar 类型)创建索引,可以使用索引前缀(即只对列的前几个字符创建索引)。例如:
CREATE INDEX idx_name_prefix ON user (name(10));

这样可以减少索引的大小,但需要注意索引前缀是否能覆盖查询条件。如果查询条件中需要的是字符串的前部分和后部分的组合,索引前缀可能无法满足覆盖查询的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2303271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电力通信物联网应用,国密网关守护电力数据安全

电力国密网关是用于保护电力调度数据网路由器和电力系统的局域网之间通信安全的电力专用网关机&#xff0c;主要为上下级控制系统之间的广域网通信提供认证与加密服务&#xff0c;实现数据传输的机密性、完整性。 国密算法网关功能特点 身份认证&#xff1a;对接入的设备和用户…

Datawhale Ollama教程笔记5

Dify 接入 Ollama 部署的本地模型 Dify 支持接入 Ollama 部署的大型语言模型推理和 embedding 能力。 快速接入 下载 Ollama 访问 Ollama 安装与配置&#xff0c;查看 Ollama 本地部署教程。 运行 Ollama 并与 Llama 聊天 ollama run llama3.1Copy to clipboardErrorCopied …

保姆级! 本地部署DeepSeek-R1大模型 安装Ollama Api 后,Postman本地调用 deepseek

要在Postman中访问Ollama API并调用DeepSeek模型&#xff0c;你需要遵循以下步骤。首先&#xff0c;确保你有一个有效的Ollama服务器实例运行中&#xff0c;并且DeepSeek模型已经被加载。 可以参考我的这篇博客 保姆级&#xff01;使用Ollama本地部署DeepSeek-R1大模型 并java…

ASP.NET Core 下载文件

本文使用 ASP .NET Core&#xff0c;适用于 .NET Core 3.1、.NET 5、.NET 6和.NET 8。 另请参阅&#xff1a; 如何在将文件发送到浏览器后自动删除该文件。 如何将文件从浏览器上传到服务器。 如何在 ASP.NET Core 应用程序中从 URL/URI 下载文件。 如果使用.NET Framework&am…

【信息系统项目管理师-案例真题】2022下半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一(24分)【问题1】(6分)【问题2】(10分)【问题3】(8分)试题二(26分)【问题1】(8分)【问题2】(8分)【问题3】(4分)【问题4】(6分)试题三(25分)【问题1】(12分)【问题2】(7分)【问题…

原来DeepSeek还能运用在系统集成-领星对接

在当今数字化转型的浪潮中&#xff0c;企业的信息化建设已成为提升运营效率、优化管理流程的关键。领星ERP与金蝶云星空作为两款在电商和财务管理领域广受欢迎的软件&#xff0c;其数据对接对于跨境电商企业来说尤为重要。本文将结合实际应用场景&#xff0c;深度解析如何通过轻…

在windows下安装windows+Ubuntu16.04双系统(上)

这篇文章的内容主要来源于这篇文章&#xff0c;给文章很详细的介绍了如何从windows下安装windowsubuntu16.04双系统。我刚开始装双系统都是参照这个方法&#xff0c;该作者前后更新了两个版本&#xff0c;在这里对其稍微进行整理一下。 一、准备&#xff1a;&#xff08;这里推…

第37章 合作之路与占坑成功

在春寒料峭的时节&#xff0c;那丝丝寒意宛如一缕缕若有若无的轻烟&#xff0c;在空气中悄然弥漫。锐创所的会议室&#xff0c;宛如一个被岁月尘封的神秘空间&#xff0c;暖黄色的灯光晕染开来&#xff0c;像是为整个房间披上了一层朦胧的薄纱&#xff0c;陈旧却又带着几分温馨…

杰和科技GAM-AI视觉识别管理系统,让AI走进零售营销

在数字化浪潮席卷全球零售业的今天&#xff0c;如何精准触达顾客需求、优化运营效率、提升门店业绩&#xff0c;成为实体商业破局的关键。 GAM-AI视觉识别管理系统 杰和科技智能零售管理系统&#xff1a;GAM-AI视觉识别管理系统&#xff0c;以AI视觉识别大数据分析边缘计算为核…

golang内存泄漏

golang也用了好几年了&#xff0c;趁着有空 整理归纳下&#xff0c;以后忘了好看下 一般认为 Go 10次内存泄漏&#xff0c;8次goroutine泄漏&#xff0c;1次是真正内存泄漏&#xff0c;还有1次是cgo导致的内存泄漏 1:环境 go1.20 win10 2:goroutine泄漏 单个Goroutine占用内存&…

Redis存储⑩Redis的事务_弱化的原子性

目录 1. MySQL和Redis事务的区别 1.1 MySQL的事务 1.2 Redis的事务 2. Redis事务操作 2.1 MULTI multi 2.2 EXEC exec 2.3 DISCARD discard 2.4 WATCH 1. MySQL和Redis事务的区别 1.1 MySQL的事务 MySQL事务复习&#xff1a; MySQL数据库⑨_事务&#xff08;四个属性…

基于Flask的京东商品信息可视化分析系统的设计与实现

【Flask】基于Flask的京东商品信息可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 系统能够灵活地执行SQL查询&#xff0c;提取出用于分析的关键数据指标。为了将这…

QML ToolButton与DelayButton的使用、详解与自定义样式

QML MenuBarItem与MenuItem的使用、详解与自定义样式 一、介绍1、ToolButton常见用法基础示例设置图标 常用属性texticonenabledshortcutcheckable & checked 信号onClickedonPressed 和 onReleased 样式和外观使用场景 2、DelayButton使用场景核心属性1. delay 核心信号1.…

JSON格式,C语言自己实现,以及直接调用库函数(一)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。以下为你提供不同场景下常见的 JSON 格式示例。 1. 简单对象 JSON 对象是由键值对组成&#xff0c;用花括号 {} 包裹&…

学习整理安装php的uuid扩展以及uuid调用方法

学习整理安装php的uuid扩展以及uuid调用方法 1、安装uuid依赖库2、下载并安装3、ini中添加扩展4、re2c版本报错5、uuid调用方法 1、安装uuid依赖库 yum -y install uuid uuid-devel e2fsprogs-devel libuuid-devel2、下载并安装 点我下载uuid安装包 wget http://pecl.php.ne…

Orange 单体架构 - 快速启动

1 后端服务 1.1 基础设施 组件说明版本MySQLMySQL数据库服务5.7/8JavaJava17redis-stackRedis向量数据库最新版本Node安装Node22.11.0 1.2 orange-dependencies-parent 项目Maven依赖版本管理 1.2.1 项目克隆 GitHub git clone https://github.com/hengzq/orange-depende…

Spring Boot 入门 与 无法解析符号 springframework 的解决

Spring Boot 入门的关键步骤 1 创建 Maven 工程 操作目的&#xff1a; 通过 Maven 工程来管理项目依赖&#xff0c;Spring Boot 本身就依赖 Maven 或 Gradle 来简化依赖管理。 操作方法&#xff1a; 打开 IDEA&#xff08;IntelliJ IDEA&#xff09;。点击 New Project&#…

3D模型在线转换工具:轻松实现3DM转OBJ

3D模型在线转换是一款功能强大的在线工具&#xff0c;支持多种3D模型格式的在线预览和互转。无论是工业设计、建筑设计&#xff0c;还是数字艺术领域&#xff0c;这款工具都能满足您的需求。 3DM与OBJ格式简介 3DM格式&#xff1a;3DM是一种广泛应用于三维建模的文件格式&…

网络安全-js安全知识点与XSS常用payloads

简介 JavaScript 是一种轻量级的编程语言&#xff0c;定义了HTML的行为。它与Java的关系类似周杰和周杰伦的关系&#xff08;即没有关系&#xff09;。 用法 HTML 中的脚本必须位于 <script> 与 </script> 标签之间。 脚本可被放置在 HTML 页面的 <body>…

ip属地是电话号码吗怎么改

在数字化时代&#xff0c;IP属地作为网络身份的一部分&#xff0c;对于许多互联网用户来说并不陌生。然而&#xff0c;关于IP属地的具体含义以及如何更改它&#xff0c;却常常让一些用户感到困惑。特别是当提到IP属地与电话号码之间的关系时&#xff0c;更是容易让人产生误解。…