第8章-2 查询执行的基础

news2025/5/13 19:18:50

        上一篇:《第8章-1 查询性能优化-优化数据访问》,接着来了解查询执行的过程,这个对sql执行有个更直观的了解。

查询执行的基础

        当希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解了这一点,很多查询优化工作实际上就是遵循一些原则让优化器能够按照预想的合理的方式运行。

        在这里,是时候回头看看我们前面讨论的内容了:MySQL执行一个查询的过程。根据图8-1可以看到,当向MySQL发送一个请求的时候,MySQL到底做了些什么:

        1,客户端给服务器发送一条SQL查询语句。

        2,服务器端进行SQL语句解析、预处理,再由优化器生成对应的执行计划。

        3,MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询。

        4,将结果返回给客户端。

                                        8-1:查询执行路径

        上面的每一步都比想象的要复杂,我们在后续章节中将继续讨论。我们会看到,在每一个阶段,查询处于何种状态。查询优化器是其中特别复杂也特别难理解的部分。还有很多的例外情况,例如,当查询使用绑定变量后,执行路径会有所不同,我们将在下一章讨论这点。

        MySQL 主要分为 Server 层引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。

        查询语句的执行流程如下:权限校验(如果命中缓存)--->查询缓存(mysql8.0后就废弃了)--->分析器--->优化器--->权限校验--->执行器--->引擎

 

MySQL的查询具体过程

当MySQL发送一个查询请求的时候,到底做了什么?

主要分为5个阶段:

1,客户端/服务端通信

2,查询缓存:

3,解析器解析

4,查询优化器

5,执行计划

6,返回结果

阶段一:客户端/服务端通信;

Mysql 客户端和服务端通信方式是采用“半双工”的通信方式。 

        单双工:指数据传输时不能实现双向通信,只能向一个方向发送数据,一方只能发送另一方就只能接收数据(比如广播);

        半双工:指数据传输时可以实现双向通信,但是同一个时刻只能允许数据在一个方向进行传输,通信时一方必须发送或者接收完才能执行一下步的操作(比如:对讲机)

        全双工:指数据传输时可以实现双向通信,双方通信时有两条通道,一个通道负责发送,一个通道进行接收,可以同时处理发送和接收数据的功能(比如:电话)

        服务端响应客户端请求时,客户端必须接收整个返回结果。因此在实际开发中,应该尽量保持查询简单且只返回必须的数据,这也是查询中尽量避免使用 `SELECT *` 和 `LIMIT` 的原因之一。

查看客户端与服务端的连接状态指令:

Show processlist ;
-- or
show full processlist

阶段二:查询缓存;

        当Mysql接收到一条查询语句时,会先去缓存进行查询,如果找到对应查询语句数据就直接把数据返回给客户端。

        缓存命中要求:SQL语句完全匹配;比如:select * from staff where staff_id=1 必须要求该条SQL语句完全一致,有差别就不行;

缓存什么时候失效:

        1、缓存数据的对应表数据被修改了,那么对应查询语句的缓存信息会失效。

        2、缓存满了后剔除对应的数据。

        正因为如此,在任何的写操作时,MySQL必须将对应表的所有缓存都设置为失效。如果查询缓存非常大或者碎片很多,这个操作就可能带来很大的系统消耗,甚至导致系统僵死一会儿。而且查询缓存对系统的额外消耗也不仅仅在写操作,读操作也不例外:

        1、任何的查询语句在开始之前都必须经过检查,即使这条SQL语句永远不会命中缓存

        2、如果查询结果可以被缓存,那么执行完成后,会将结果存入缓存,也会带来额外的系统消耗

        基于此,我们要知道并不是什么情况下查询缓存都会提高系统性能,缓存和失效都会带来额外消耗,只有当缓存带来的资源节约大于其本身消耗的资源时,才会给系统带来性能提升。如果系统确实存在一些性能问题,可以尝试打开查询缓存,并在数据库设计上做一些优化,比如:

        1、多个小表代替一个大表,注意不要过度设计

        2、批量插入代替循环单条插入

        3、合理控制缓存空间大小,一般来说其大小设置为几十兆比较合适

        4、可以通过SQL_CACHE和SQL_NO_CACHE来控制某个查询语句是否需要进行缓存

        最后的忠告是不要轻易打开查询缓存,特别是写密集型应用。如果你实在是忍不住,可以将query_cache_type设置为DEMAND,这时只有加入SQL_CACHE的查询才会走缓存,其他查询则不会,这样可以非常自由地控制哪些查询需要被缓存。

相关指令:

查看缓存状态:

Show variables like ‘query_cathe%’;

开启/关闭缓存:

set query_cache_type =ON/set query_cache_type =OFF;

在SQL中指定不使用缓存:

select SQL_NO_CACHE * from table;

查看缓存命中情况:

Show status like ‘Qcache%’;

阶段三:查询优化处理;

查询处理阶段主要包括解析器对SQL解析处理然后优化SQL生成执行计划;

Parser解析器对SQL解析

        通过SQL的关键字将SQL分解成对应规则的数据结构(解析树),然后使用MYSQL的语法验证规则对SQL语法规则进行验证(如关键字、语法、关键字顺序);

Optimizer: 查询优化器

        当语法验证通过之后,优化器会将SQL进行分析,通过随机数据的抽选查询成本的计算,最后从众多执行计划中选择一条最优的执行计划;

        多数情况下,一条查询可以有很多种执行方式,最后都返回相应的结果。优化器的作用就是找到这其中最好的执行计划。
        最优执行计划是根据一些列的统计信息计算得来的,这些统计信息包括:每张表或者索引的页面个数、索引的基数、索引和数据行的长度、索引的分布情况等等。
有非常多的原因会导致MySQL选择错误的执行计划,比如统计信息不准确、不会考虑不受其控制的操作成本(用户自定义函数、存储过程)、MySQL认为的最优跟我们想的不一样(我们希望执行时间尽可能短,但MySQL值选择它认为成本小的,但成本小并不意味着执行时间短)等等。

        MySQL的查询优化器是一个非常复杂的部件,它使用了非常多的优化策略来生成一个最优的执行计划:

查询优化器原则

覆盖索引扫描

        如:select id from user_info 当id列是索引时,将直接返回索引的数据,而不需要去查询具体的表数据。

等值传播

        如:where b>a and a=5 改成 b>5 and a=5;

IN的优化

        把or 转成in(),mysql中对in进行了优化,首先对in 里面的参数进行排序,然后会进行二分法匹配优化。

关联查询优化

        将可转换的外连查询转为内连。

        还有子查询优化,提前终止查询 策略等等。

阶段四:调用查询存储引擎;

        查询优化阶段生成了对应的执行计划后,mysql根据对应的执行计划调用存储引擎API 执行查询。

阶段五:返回客户端结果集;

        一旦Mysql 查询到一条数据结果集就会向客户端逐步返回数据,这样避免了服务端缓存太多的查询结果,就算没有查询到任何结果集也会向客户端返回一些信息(比如像该查询影响的行数数据);

如果开启了缓存,mysql会同时向缓存里面保存查询结果。

MySQL整个查询执行过程,总的来说分为5个阶段:

        阶段一:客户端向MySQL服务器发送一条查询请求

        阶段二:服务器首先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段

        阶段三:服务器进行SQL解析、预处理、再由优化器生成对应的执行计划

        阶段四:MySQL根据执行计划,调用存储引擎的API来执行查询

        阶段五:将结果返回给客户端,同时缓存查询结果

 

  上一篇:《第8章-1 查询性能优化-优化数据访问》

  下一篇:《第8章-3 查询性能优化1》

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

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

相关文章

java面试OOM汇总

在正式 Minor GC 前,JVM 会先检查新生代中对象,是比老年代中剩余空间大还是小。假如 Minor GC之后 Survivor 区放不下剩余对象,这些对象就要进入老年代 老年代剩余空间大于新生代中的对象大小,那就直接 Minor GC, GC 完…

react-diff-viewer 如何实现语法高亮

前言 react-diff-viewer 是一个很好的 diff 展示库,但是也有一些坑点和不完善的地方,本文旨在描述如何在这个库中实现自定义语法高亮。 Syntax highlighting is a bit tricky when combined with diff. Here, React Diff Viewer provides a simple rend…

自定义prometheus exporter实现监控阿里云RDS

# 自定义 Prometheus Exporter 实现多 RDS 数据采集## 背景1. Prometheus 官网提供的 MySQL Exporter 对于 MySQL 实例只能一个进程监控一个实例,数据库实例很多的情况下,不方便管理。 2. 内部有定制化监控需求,RDS 默认无法实现,…

【计算机网络】--tcp三次握手

文章目录 示意图:抓包结果:第一次握手(Client → Server)第二次握手(Server → Client)第三次握手(Client → Server)为什么是三次握手 不是两次或者四次 示意图: 抓包结…

UI-TARS: 基于视觉语言模型的多模式代理

GitHub:https://github.com/bytedance/UI-TARS 更多AI开源软件:发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI 基于视觉语言模型(Vision-Language Model)的 GUI 代理应用,允许用户通过自然语言控制电脑操…

Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)

1. 整体架构概览 Spark SQL的运行过程可以想象成一个"SQL查询的加工流水线",从原始SQL语句开始,经过多个阶段的处理和优化,最终变成分布式计算任务执行。主要流程如下: SQL Query → 解析 → 逻辑计划 → 优化 → 物理…

【计算机网络】网络IP层

📚 博主的专栏 🐧 Linux | 🖥️ C | 📊 数据结构 | 💡C 算法 | 🅒 C 语言 | 🌐 计算机网络 上篇文章:传输层协议TCP 下篇文章:数据链路层 文章摘要&#xff1…

一天学会Maven

一、Maven简介和快速入门 1.1 Maven介绍 Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件),使用 Maven 可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。 总结:Maven就是一个软件&#xf…

变量函数实战:高保真APP原型“发票页面”动态交互教程

变量函数是高保真交互原型设计中常见的高级交互功能,能够避免重复复制与手动修改页面元素和逻辑标注,让演示更有真实体验感。本文分享一个高保真APP交互原型页面的实操案例,结合原型设计工具中的变量函数与逻辑判断功能,手把手教你…

Spring Boot 3 + Undertow 服务器优化配置

优化背景 当你的application需要支持瞬时高并发的时候,tomcat已经不在是最优的选择,我们可以改为Undertow,并对其进行优化。 Undertow 是一个轻量级的、高性能的Java Web 服务器,由JBoss 开发并开源。它是基于非阻塞(…

7系列 之 OSERDESE2

背景 《ug471_7Series_SelectIO.pdf》介绍了Xilinx 7 系列 SelectIO 的输入/输出特性及逻辑资源的相关内容。 第 1 章《SelectIO Resources》介绍了输出驱动器和输入接收器的电气特性,并通过大量实例解析了各类标准接口的实现。 第 2 章《SelectIO Logic Resource…

vue3+flask+sqlite前后端项目实战

基础环境安装 pycharm 下载地址: https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows vscode 下载地址 https://code.visualstudio.com/docs/?dvwin64user python 下载地址 https://www.python.org/downloads/windows/ Node.js(含npm…

Java 线程的堆栈跟踪信息

Java 线程的堆栈跟踪信息,展示了线程的当前状态和执行位置。以下是详细解释: 线程基本信息 "Thread-0" #16 prio5 os_prio0 cpu0.00ms elapsed16.29s tid0x00000243105a4130 nid0x5384 waiting on condition [0x0000007687ffe000]线程名称…

【计算机视觉】OpenCV实战项目:Long-Exposure:基于深度学习的长时间曝光合成技术

Long-Exposure:基于深度学习的长时间曝光合成技术 项目概述与技术背景项目核心功能技术原理 环境配置与安装硬件要求建议详细安装步骤可选组件安装 实战应用指南1. 基础使用:视频转长曝光2. 高级模式:自定义光轨合成3. 批量处理模式 技术实现…

传输层协议UDP和TCP

传输层协议UDP和TCP 1、UDP2、TCP2.1、TCP协议段格式2.2、确认应答(ACK)机制2.3、超时重传机制2.4、连接管理机制2.5、理解CLOSE_WAIT状态2.6、理解TIME_WAIT状态2.7、流量控制2.8、滑动窗口2.9、拥塞控制2.10、延迟应答2.11、捎带应答2.12、面向字节流2.13、粘包问题2.14、TCP…

浅谈大语言模型原理

1.反向传播算法 背景 反向传播算法是当前深度学习的核心技术。 神经网络 x是输入,o是输出,w是需要训练的参数(w有初始值)三层全连接的神经网络:输入层、隐藏层、输出层 激活函数 f ( x ) 1 1 x − 1 f(x)\frac…

Clickhouse 迁移到 Doris 的最佳实践

一、引言 在将数据从 Clickhouse 迁移到 Apache Doris / SelectDB Cloud 的过程中,涉及表结构迁移、查询语句迁移以及数据迁移等多个关键环节。每个环节都有其复杂性和需要注意的细节,本文将详细介绍这些内容及对应的最佳实践方法。 二、表结构迁移 &…

WebSocket的原理及QT示例

一.WebSocket 介绍 1.概述 WebSocket 是一种在单个 TCP 连接上进行全双工通讯的协议,它在 2011 年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。与传统的 HTTP 协议不同,WebSocket 允许服务器和客户端之间进行实时、双向的数据传输&a…

vue3:十二、图形看板- echart图表-柱状图、饼图

一、效果 如图展示增加了饼图和柱状图,并且优化了浏览器窗口大小更改,图表随着改变 二、 饼图 1、新建组件文件 新增组件EchartsExaminePie.vue,用于存储审核饼图的图表 2、写入组件信息 (1)视图层 写入一个div,写入变量chart和图表宽高 <template><div ref…

2025年best好用的3dsmax插件和脚本

copitor 可以从一个3dsmax场景里将物体直接复制到另一个场景中 Move to surface 这个插件可以将一些物体放到一个平面上 instancer 实体器&#xff0c;举例&#xff1a;场景中有若干独立的光源&#xff0c;不是实体对象&#xff0c;我们可以使用instancer将他变成实体。 paste …