【MySQL】深入理解MySQL索引优化器原理(MySQL专栏启动)

article/2025/11/7 6:48:44

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。

 

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

 

🏆 InfoQ签约作者、CSDN专家博主/后端领域优质创作者/内容合伙人、阿里云专家/签约博主、51CTO专家 🏆

 

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 

本文目录

本文目录

本文导读

一、MySQL 优化器是如何选择索引的

1、MySQL数据库组成

2、MySQL数据库成本计算

二、MySQL查询成本

三、SELECT 执行过程

总结


本文导读

本文将解读MySQL数据库查询优化器(CBO)的工作原理。简单介绍了MySQL Server的组成,MySQL优化器选择索引额原理以及SQL成本分析,最后通过 select 查询总结整个查询过程。

一、MySQL 优化器是如何选择索引的

下面我们来看这张表,SUB_ODR_ID字段创建了相关的 2 个索引,根据我们前面所学我们建立一个PRIMARY KEY (`ID`)自增主键索引,(`LOG_ID`, `SUB_ODR_ID`)设置为联合索引、唯一索引,两个时间CREATE_TIME、UPDATE_TIME分别设置两个索引。

CREATE TABLE `***`  (`ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',`LOG_ID` varchar(32) NOT NULL COMMENT '交易流水号',`ODR_ID` varchar(32) NOT NULL COMMENT '父单号',`SUB_ODR_ID` varchar(32) NOT NULL COMMENT '子单号',`CREATE_TIME` datetime(0) NOT NULL COMMENT '创建时间',`CREATE_BY` varchar(32) NOT NULL COMMENT ' 创建人',`UPDATE_TIME` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',`UPDATE_BY` varchar(32) NOT NULL COMMENT '更新人',PRIMARY KEY (`ID`) USING BTREE,UNIQUE INDEX `UNQ_LOG_SUBODR_ID`(`LOG_ID`, `SUB_ODR_ID`) USING BTREE,INDEX `IDX_ODR_ID`(`ODR_ID`) USING BTREE,INDEX `IDX_SUB_ID`(`SUB_ODR_ID`) USING BTREE,INDEX `IDX_CREATE_TIME`(`CREATE_TIME`) USING BTREE,INDEX `IDX_UPDATE_TIME`(`UPDATE_TIME`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 SET = utf8 COLLATE = utf8_general_ci COMMENT = '分摊业务明细表' ROW_FORMAT = Dynamic;

在查询字段 SUB_ODR_ID 中,理论上可以使用三个相关的索引:UNQ_LOG_SUBODR_ID、IDX_SUB_ID,MySQL优化器如何从这三个索引中进行选择?

在关系数据库中,B+树只是用于存储的数据结构。

如何使用它取决于数据库的优化器。优化器确定特定索引的选择,即执行计划。优化器的选择基于成本,成本越低,首选指数越高。

1、MySQL数据库组成

MySQL数据库由Server(服务器)层和Engine(引擎)层组成。

Serve层有SQL分析器、SQL优化器和SQL执行器,负责SQL语句的具体执行过程。

Engine层负责存储特定数据,例如最常用的InnoDB存储引擎,以及用于在内存中存储临时结果集的TempTable引擎。

SQL优化器将分析所有可能的执行计划,并选择成本最低的执行。这个优化器被称为CBO(基于成本的优化器)。

2、MySQL数据库成本计算

在 MySQL中,一条 SQL 的计算成本计算,很好理解,就是访问数据库(数据库页、磁盘)+处理数据。

CPU成本,表示计算成本,例如索引键值的比较、记录值的比较和结果集的排序。这些操作都在服务器层完成

IO成本,表示引擎级IO的成本,MySQL 8.0可以通过区分表的数据是否在内存中来分别计算读取内存IO和磁盘IO的成本。

Cost  = Server Cost + Engine Cost  = CPU Cost + IO Cost

MySQL优化器认为,如果一段SQL需要创建一个基于磁盘的临时表,那么此时的成本是最大的,是基于内存的临时表的20倍。比较索引键值和记录的成本很低,但如果要比较的记录很多,成本就会非常大。

MySQL 优化器认为,从磁盘读取的开销是内存开销的 4 倍(成本不是一成不变的会根据硬件变化)。

二、MySQL查询成本

查看各成本的值,MySQL优化器的工作原理,我们执行下面这行SQL语句,分析执行过程,MySQL 索引选择是基于 SQL 执行成本

EXPLAIN FORMAT=json 
select * from test.fork_business_detail f where f.sub_odr_id = ''

read_cost表示从InnoDB存储引擎读取的成本;

eval_cost表示服务器层的CPU成本;

prefix_cost表示SQL的总成本;

data_read_per_join 表示读取记录中的字节总数。

{"query_block": {"cost_info": {"query_cost": "1.20"},"table": {"access_type": "ref","possible_keys": ["IDX_SUB_ID"],"key": "IDX_SUB_ID","used_key_parts": ["SUB_ODR_ID"],"key_length": "98","ref": ["const"],"cost_info": {"read_cost": "1.00","eval_cost": "0.20","prefix_cost": "1.20","data_read_per_join": "1K"},"used_columns": ["ID","LOG_ID","ODR_ID","SUB_ODR_ID","CREATE_TIME","CREATE_BY","UPDATE_TIME","UPDATE_BY"]}}
}

三、SELECT 执行过程

如何提高MySQL的查询性能?首先,您需要了解查询优化器进行SQL处理的整个过程。SELECT SQL 的执行过程为例,如下图所示: 

客户端向服务器发送SELECT查询;服务器首先检查查询缓存。如果缓存被命中,存储在缓存中的结果将立即返回。否则,进入下一阶段;

服务器执行SQL解析、预处理,查询优化器生成相应的执行计划;MySQL根据优化器生成的执行计划调用存储引擎的API执行查询;结果将返回到客户端,并同时放入查询缓存。

总结

本文将解读MySQL数据库查询优化器(CBO)的工作原理。简单介绍了MySQL Server的组成,MySQL优化器选择索引额原理以及SQL成本分析,最后通过 select 查询总结整个查询过程。


http://chatgpt.dhexx.cn/article/UAfOgNYu.shtml

相关文章

mysql 索引优化

一、mysql索引建立原则 二、通过 EXPLAIN 分析 SQL 执行计划 可以知道以下内容: 假设现在我们使用 EXPLAIN 命令查看当前 SQL 是否使用了索引,先通过 SQL EXPLAIN 导出相应的执行计划如下: 下面对图示中的每一个字段进行一个说明&#x…

【MySQL】MySQL索引优化——从原理分析到实践对比

目录 使用TRACE分析MySQL优化 开启TRACE TRACE 结果集 ORDER BY & GROUP BY 优化 优化方式 分页优化 不同场景的优化方式 JOIN关联优化 算法介绍 优化方式 COUNT优化 优化方式 使用TRACE分析MySQL优化 某些情况下,MySQL是否走索引是不确定的[,,_,,…

MySQL索引常见面试题(2022版)

目录 为什么要建立索引? 哪些情况适合建立索引? 哪些情况下不适合建索引? 为什么索引是使用B树?(重点) 索引分为那几类? 什么是聚簇索引?(重点) 使用聚…

mysql数据库索引优化【建议收藏】

在我们程序员玩数据库的时候,经常会写sql,但是决定一个sql的好坏往往是效率,于是我们需要不断的去优化我们的sql,写一句让人称赞的sql是非常不容易的,也是需要大家有非常深厚的功底,所以优化路漫漫&#xf…

MySQL索引优化

MySQL索引优化 一、优化索引的方法二、优化步骤前缀索引优化覆盖索引优化主键索引最好是自增的索引最好设置为NOT NULL防止索引失效 总结 一、优化索引的方法 这里说一下几种常见优化索引的方法: 前缀索引优化; 覆盖索引优化; 主键索引最好是…

Android底层到上层的开发流程

安卓系统整体框架图如下: 简单总结如下: 1、在kernel层编写你的驱动程序:生成设备文件节点跟上一层传输数据,主要调用函数copy_to_user和copy_from_user,注意赋节点权限问题。 2、在HAL层封装对上提供的函数接口&…

【Android】Android底层开发实战

本书分为四个部分:第一部分为预备知识篇,简要介绍嵌入式系统的定义与软硬件开发以及Android开发环境的搭建。第二部分为系统结构篇,主要介绍Android系统的源码结构、内核与相关工具以及环境库。第三部分为驱动设计篇,主要介绍Andr…

我做了几年的Android应用层开发,为什么还要去学习安卓系统知识?

作为一个工作了好几年的Android应用层开发者,我准备在工作之余干一件事情,那就是学习Android系统知识,为什么要做这个决定呢? 其主要原因是想在Android应用层开发进阶 这个说起来并非易事,可能在很多人的认知里&…

一个Android应用层开发如何转型深入Android Framework?

作为一个工作了好几年的Android应用层开发者,准备在工作之余干一件事情,那就是分享一些Android系统知识,为什么决定要做这个呢,理由如下: 帮助更多人转型Android系统开发 不知何时起,单纯的Android应用层…

android底层开发-android基础架构

android architecture 在安卓中,最经典的架构就是分四层,分别是application、framework、libraries、kernel四层,通过这四层将android的整个架构都丰满起来 其架构图如下 android 系统组成 Process FW: android 系统固件&#…

Android Framework 开发揭解密,移动开发者必须掌握的底层原理

作为过来人,发现很多学习者和实践者都在 Android Framework上面临着很多的困扰,比如: 工作场景中遇到难题,往往只能靠盲猜和感觉,用临时性的补救措施去掩盖,看似解决了问题,但下次同样的问题又会…

Android系统底层架构【译】

Android系统底层架构 转载请注明来源:http://blog.csdn.net/lifeshow 设备移植 Android提供了设备移植和支持方面有较大的自由度,可以制定自有的设备规范和驱动。通过硬件抽象层(HAL-Hardware Abstraction Layer),可以…

嵌入式Android底层开发

嵌入式Linux主要有这几部分&#xff1a; Bootloader&#xff1a;主要用于引导Linux内核到内存中&#xff0c;让内核进行自解压并运行 zImage&#xff1a;带自解压的Linux内核 <Board>.dtb&#xff1a;每个型号的主板都有对应的设备树(保存对应的设备型号等信息&#x…

android 底层系统开发,Android底层

概述-Android系统架构 Android系统架构 概述-Application Application Android平台不仅仅是操作系统&#xff0c;同时也包含了许多应用&#xff0c;如桌面&#xff0c;浏览器&#xff0c;视频客户端&#xff0c;摄像头等。用JAVA编写&#xff0c;可以被开发人员开发的其他应用程…

Android 开发之 ---- 底层驱动开发(二)

Android 设备驱动&#xff08;下&#xff09; MTD 驱动 Flash 驱动通常使用 MTD &#xff08;memory technology device )&#xff0c;内存技术设备。 MTD 的字符设备&#xff1a; /dev/mtdX 主设备号 90. MTD 的块设备&#xff1a; /dev/block/mtdblockX 主设备号 13. MTD 驱…

写给Android App开发人员看的Android底层知识(1)

这个系列的文章一共8篇&#xff0c;我酝酿了很多年&#xff0c;参考了很多资源&#xff0c;查看了很多源码&#xff0c;直到今天把它写出来&#xff0c;也是战战兢兢&#xff0c;生怕什么地方写错了&#xff0c;贻笑大方。 &#xff08;一&#xff09;引言 早在我还是Android菜…

读懂底层,才是安卓真正开始的时候

对于android开发&#xff0c;我们大部分工作都是在应用层&#xff0c;但为了体现"技术含量"&#xff0c;以及"知其所以然"&#xff0c;以便在遇到具体问题时不至于束手无策&#xff0c;因此有必要了解底层的工作机制。 比如Android NDK 开发可能在平时的项…

Android 开发之 ---- 底层驱动开发

说到 android 驱动是离不开Linux驱动的。Android内核采用的是Linux2.6内核&#xff08;最近Linux 3.3已经包含了一些Android代码&#xff09;。但Android并没有完全照搬Linux系统内核&#xff0c;除了对Linux进行部分修正&#xff0c;还增加了不少内容。android 驱动主要分两种…

Android 开发之 ---- 底层驱动开发(一)

驱动概述 说到 android 驱动是离不开 Linux 驱动的。Android 内核采用的是 Linux2.6 内核 &#xff08;最近Linux 3.3 已经包含了一些 Android 代码&#xff09;。但 Android 并没有完全照搬 Linux 系统内核&#xff0c;除了对Linux 进行部分修正&#xff0c;还增加了不少内容。…

Android底层开发

学习书籍&#xff1a;Android底层开发实践 使用代码&#xff1a;AOSP源码 带的行表示关键点&#xff1b; 橙色背景的文字表示&#xff1a;整编log分析的关键字 绿色“待补充”文字表示&#xff1a;有待补充内容 -----第三章 Android系统开发环境搭建 3.1 Android上的开…