当前位置: 首页 > news >正文

MySQL查询优化(三):深度解读 MySQL客户端和服务端协议

如果需要从 MySQL 服务端获得很高的性能,最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些,大部分的查询优化是有据可循的,从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程:

  1. 客户端将 SQL 语句发送到服务端。
  2. 服务端检查查询缓存。如果缓存中已有数据,则直接返回缓存结果;否则,将 SQL 语句传递给下一环节。
  3. 服务端解析、预处理和优化 SQL 语句后,传递到查询优化器中形成查询计划。
  4. 查询执行引擎通过调用存储引擎接口执行查询计划。
  5. 服务端将查询结果返回给客户端。

上述的几个步骤都有其复杂性,接下来几篇文章将详细讲述各个环节。查询优化过程尤其复杂,并且理解这一环节很重要。


mysql 查询完整过程
MySQL 客户端/服务端协议

虽然并不需要了解 MySQL 客户端/服务端协议的内部细节,但需要从高应用层面理解其是如何工作的。这个协议是半双工的,这意味着 MySQL 服务端不同同时发送和接收消息,以及不可以将消息拆成多条短消息发送。这种机制一方面使得 MySQL 的通信简单快速,另一方面也增加了一些限制。例如,这意味着无法进行流控,一旦一方发送了消息,另一方在响应前必须接收整个消息。这就好像来回打乒乓球一样,同一时间只有一方有球,只有接到了球才能把它打回去。

客户端通过单个数据包将查询语句发送给服务端,因此在存在大的查询语句时配置 max_allowed_packet 很重要。一旦客户端发送查询语句后,它就只能等待返回结果。

相反,服务端的响应通常是由多个数据包组成的。一旦服务端响应后,客户端必须获取整个结果集。客户端没法简单地获取几行然后告诉服务端不要再发送剩余的数据。如果客户端仅仅需要返回数据前面的几行,只能是等待服务端全部数据返回后再从中丢弃不需要的数据,或者是粗暴地断开连接。不管哪种方式都不是好的选择,因此合适的 LIMIT子句就显得十分重要。

大部分的 MySQL连接库支持获取整个结果集并在内存中缓存起来,或者是获取需要的数据行。默认的行为通常是获取整个结果集然后在内存缓存。知道这一点很重要,因为 MySQL 服务端在所有请求的数据行没返回前,不会释放这次查询的锁和资源。大部分客户端库会让你感觉数据是从服务端获取的,实际上这些数据可能仅仅是从缓存中读取的。这在大部分时间是没问题的,但对于耗时很久或占据很多内存的大数据量查询来说就不合适了。如果指定了不缓存查询结果,那么占用的内存会更小,并且可以更快地处理结果。缺点是这种方式会在查询时引起
服务端的锁和资源占用。

以 PHP 为例,以下是PHP常用的查询代码:

<?php
$link = mysql_connect('localhost', 'user', 'password');
$result = mysql_query('SELECT * FROM huge_table', $link);
while ($row = mysql_fetch_array($result)) {//处理数据结果
}?>

这个代码看起来好像是只获取了需要的数据行。然而,这个查询通过 mysql_query 的调用后实际上将全部结果放到了内存中。而 while 循环实际上是对内存中的数据进行循环迭代。相反,如果使用 mysql_unbuffered_query 替代 mysql_query 的话,那就不会缓存结果。

<?php
$link = mysql_connect('localhost', 'user', 'password');
$result = mysql_unbuffered_query('SELECT * FROM huge_table', $link);
while ($row = mysql_fetch_array($result)) {//处理数据结果
}?>

不同的编程语言处理缓存覆盖的方式不同。例如,Perl 的 DBD::mysql 驱动需要通过 mysql_use_result 属性指定 C 语音客户端库(默认是 mysql_buffer_result),示例如下:

#!/usr/bin/perluse DBI;
my $dbn = DBI->connect('DBI:mysql:;host=localhost', 'user', 'password');
my $sth = $dbn->prepare('SELECT * FROM huge_table', {mysql_use_result => 1});
$sth->execute();
while (my $row = $sth->fetchrow_array()) {#处理数据结果
}

注意到 prepare 指定了使用结果而不是缓存结果。也可以通过在连接的时候指定,这会使得每次查询都不缓存。

my $dbn = DBI->connect('DBI:mysql:;mysql_use_result=1;host=localhost', 'user', 'password');
最后编辑于:2025-01-18 16:58:25


喜欢的朋友记得点赞、收藏、关注哦!!!

相关文章:

MySQL查询优化(三):深度解读 MySQL客户端和服务端协议

如果需要从 MySQL 服务端获得很高的性能&#xff0c;最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些&#xff0c;大部分的查询优化是有据可循的&#xff0c;从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程&#xff1a; 客户端…...

vue3相关知识点

title: vue_1 date: 2025-01-28 12:00:00 tags:- 前端 categories:- 前端vue3 Webpack ~ vite vue3是基于vite创建的 vite 更快一点 一些准备工作 准备后如图所示 插件 Main.ts // 引入createApp用于创建应用 import {createApp} from vue // 引入App根组件 import App f…...

基于springboot+vue的流浪动物救助系统的设计与实现

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

MySQL(单表访问)

今天是新年&#xff0c;祝大家新年快乐&#xff0c;但是生活还是得继续。 后面也会持续更新&#xff0c;学到新东西会在其中补充。 建议按顺序食用&#xff0c;欢迎批评或者交流&#xff01; 缺什么东西欢迎评论&#xff01;我都会及时修改的&#xff01; 大部分截图和文章采…...

UE5.3 C++ CDO的初步理解

一.UObject UObject是所有对象的基类&#xff0c;往上还有UObjectBaseUtility。 注释&#xff1a;所有虚幻引擎对象的基类。对象的类型由基于 UClass 类来定义。 这为创建和使用UObject的对象提供了 函数&#xff0c;并且提供了应在子类中重写的虚函数。 /** * The base cla…...

SpringBoot 中的测试jar包knife4j(实现效果非常简单)

1、效果图 非常快的可以看见你实现的接口 路径http://localhost:8080/doc.html#/home 端口必须是自己的 2、实现效果 2.1、导入jar包 <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-star…...

Java Web 开发基础介绍

Java学习资料 Java学习资料 Java学习资料 一、引言 在当今数字化时代&#xff0c;Web 应用无处不在。Java 凭借其强大的功能、良好的跨平台性和丰富的开发框架&#xff0c;成为 Web 开发领域的热门选择之一。Java Web 开发允许开发者构建动态、交互式的 Web 应用程序&#x…...

Android Studio:视图绑定的岁月变迁(2/100)

一、博文导读 本文是基于Android Studio真实项目&#xff0c;通过解析源码了解真实应用场景&#xff0c;写文的视角和读者是同步的&#xff0c;想到看到写到&#xff0c;没有上帝视角。 前期回顾&#xff0c;本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

LabVIEW春节快乐

尊敬的LabVIEW开发者与用户朋友们&#xff1a; 灵蛇舞动辞旧岁&#xff0c;春风送暖贺新年&#xff01;值此癸巳蛇年新春佳节来临之际&#xff0c;向每一位深耕LabVIEW开发领域的伙伴致以最诚挚的祝福&#xff1a;愿您与家人在新的一年里平安顺遂、阖家幸福&#xff0c;事业如…...

rewrite规则

NGINX 中 rewrite最后的标记含义&#xff1a; flag标记有&#xff1a; last 相当于Apache里的[L]标记&#xff0c;表示完成rewrite&#xff0c;匹配完&#xff0c;再向下匹配。地址栏会显示跳转后的地址 break 终止匹配, 不再匹配后面的rewrite规则&#xff0c;地址栏会显示跳…...

Android车机DIY开发之学习篇(七)NDK交叉工具构建

Android车机DIY开发之学习篇(七)NDK交叉工具构建 1.ubuntu安装GCC sudo apt-get update sudo apt-get install gcc g sudo gcc --version sudo g --version 2.测试GCC VSCODE中新建Hello.c编译 #include <stdio.h> int main(void) { printf(“Hello, this is a progr…...

【初/高中生讲机器学习】0. 本专栏 “食用” 指南——写在一周年之际⭐

创建时间&#xff1a;2025-01-27 首发时间&#xff1a;2025-01-29 最后编辑时间&#xff1a;2025-01-29 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名高一学生&#xff0c;热爱计…...

虚幻基础11:坐标计算旋转计算

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 坐标line startget actor rotationget forward vector 旋转计算 坐标 ue中通常使用向量计算坐标。 line start 起始坐标点。 get actor rotation 获取旋转值&#xff1a; 当前角色朝向 get forward vector 获…...

Rust:Rhai脚本编程示例

当然&#xff0c;以下是一个简单的Rhai脚本编程示例&#xff0c;展示了如何在Rust中使用Rhai执行脚本。 首先&#xff0c;你需要确保你的Rust项目中包含了rhai库。你可以在你的Cargo.toml文件中添加以下依赖项&#xff1a; [dependencies] rhai "0.19" # 请检查最…...

关于el-table翻页后序号列递增的组件封装

需求说明&#xff1a; 项目中经常会用到的一个场景&#xff0c;表格第一列显示序号&#xff08;1、2、3...&#xff09;&#xff0c;但是在翻页后要递增显示序号&#xff0c;例如10、11、12&#xff08;假设一页显示10条数据&#xff09;&#xff0c;针对这种情况&#xff0c;封…...

【深度学习】softmax回归

softmax回归 回归可以用于预测多少的问题。 比如预测房屋被售出价格&#xff0c;或者棒球队可能获得的胜场数&#xff0c;又或者患者住院的天数。 事实上&#xff0c;我们也对分类问题感兴趣&#xff1a;不是问“多少”&#xff0c;而是问“哪一个”&#xff1a; 某个电子邮…...

设计模式-建造者模式、原型模式

目录 建造者模式 定义 类图 优缺点 角色 建造者模式和工厂模式比较 使用案例 原型模式 定义 类图 优缺点 应用场景 应用类型 浅克隆 深克隆 建造者模式 定义 将一个复杂的对象的构造与它的表示分离&#xff0c;使同样的构建过程可以创建不同的表示&#xff0c;…...

【Redis】List 类型的介绍和常用命令

1. 介绍 Redis 中的 list 相当于顺序表&#xff0c;并且内部更接近于“双端队列”&#xff0c;所以也支持头插和尾插的操作&#xff0c;可以当做队列或者栈来使用&#xff0c;同时也存在下标的概念&#xff0c;不过和 Java 中的下标不同&#xff0c;Redis 支持负数下标&#x…...

三个不推荐使用的线程池

线程池的种类 其实看似这么多的线程池&#xff0c;都离不开ThreadPoolExecutor去创建&#xff0c;只不过他们是简化一些参数 newFixedThreadPool 里面全是核心线程 有资源耗尽的风险&#xff0c;任务队列最大长度为Integer.MAX_VALUE&#xff0c;可能会堆积大量的请求&#xff…...

mybatis(78/134)

前天学了很多&#xff0c;关于java的反射机制&#xff0c;其实跳过了new对象&#xff0c;然后底层生成了字节码&#xff0c;创建了对应的编码。手搓了一遍源码&#xff0c;还是比较复杂的。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE …...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...