MySQL之查询性能优化(三)

查询性能优化

重构查询的方式

在优化有问题的查询时,目标应该是找到一个更优的方法获得实际需要的记过——而不是一定总是需要从MySQL获取一模一样的结果集。有时候,可以将查询转换一种写法让其返回一样的结果,但是性能更好。但也可以通过修改应用代码,用另一种方式完成查询,最终达到一样的目的。

一个复杂查询还是多个简单查询

设计查询的时候一个需要考虑的重要问题是,是否需要将一个复杂的查询分成多个简单的查询,在传统实现中,总是强调需要数据库层完成尽可能多的工作,这样做的逻辑在于以前总是认为网络通信、查询解析和优化是一件代价很高的事情。但是这样的想法对于MySQL并不适用,MySQL从设计上让连接和断开连接都很轻量级,在返回一个小的查询结果方面很高效。现代的网络速度比以前要快很多,无论是贷款还是延迟。在某些版本的MySQL上,即使在一个通用服务器上,也能够运行超过10万的查询,即使是一个千兆网卡(1000Mbps / 8 bit = 125M/s)也能轻松满足每秒超过2000次的查询。所以运行多个小查询现在已经不是大问题了。MySQL内部每秒能够扫描内存中上百万行数据,相比之下,MySQL响应数据给客户端就慢得多了。在其他条件都相同的时候,适用尽可能少的查询当然是更好地。但是有时候,将一个大查询分解为多个小查询是很有必要的。别害怕这样做,好好衡量一下这样做是不是会减少工作量。
不过,在应用设计的时候,如果一个查询能够胜任时还写成多个独立查询是不明智的。例如,有些应用对一个数据表做10次独立的查询来返回10行数据,每个查询返回一条结果,查询10次

切分查询

有时候对于一个大查询我们需要"分而治之",将大查询切分成小查询,每个查询功能完全一样,只完成一小部分,每次只返回一小部分查询结果。删除旧的数据就是一个很好的例子。定期地清除大量数据时,如果用一个大的语句一次性完成的话,则可能需要依次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但很重要的查询。将一个大的DELETE语句切分成多个较小的查询可以尽可能小地影响MySQL性能,同时还可以减少MySQL复制地延迟。例如,我们需要每个月运行一次下面的查询:

mysql> DELETE FROM message WHERE created < DATE_SUB(NOW(), INTERVAL 3 MONT

那么可以用类似下面的办法来完成同样的工作:

rows_affected=0
do {
rows_affected = do_query(
"DELETE FROM message WHERE created < DATE_SUB(NOW(), INTERVAL 3 MONTH)
LIMIT 10000"
)
} while rows_affected > 0

一次性删除一万行数据一般来说是一个比较高效而且对服务器影响也是最小的做法(如果是事务型引擎,很多时候小事务能够更高效),同时,需要注意的是,如果每次删除数据后,都暂停一会儿再做下一次删除,这样也可以将服务器上原本一次性的压力分散到一个很长的时间段中,就可以大大降低对服务器的影响,还可以大大减少删除时锁的持有时间

分阶关联查询

很多高性能的应用都会对关联查询进行分解。简单地,可以对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。例如,下面这个查询:

mysql> SELECT * FROM tag-> JOIN tag_post ON tag_post.tag_id=tag.id-> JOIN post ON tag_post.post_id=post.id-> WHERE tag.tag = 'mysql';

可以分解成下面这些查询来代替:

mysql> SELECT * FROM tag WHERE tag = 'mysql';
mysql> SELECT * FROM tag_post WHERE tag_id = 1234;
mysql> SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);

到底为什么要这样做呢?乍一看,这样做并没有什么好处,原本一条查询,这里却变成多条查询,返回的结果又是一模一样的。事实上,用分解关联查询的方式重构查询有如下的优势:

  • 1.让缓存的效率更高。许多应用程序可以方便地缓存单表查询对应的结果对象。例如,上面查询中的tag已经被缓存了,那么应用就可以跳过第一个查询。再例如,应用中已经缓存了ID为123、567、9098的内容,那么第三个查询中的IN()中就可以少几个ID.另外,对MySQL的查询缓存来说(Query Cache),如果关联中的某个表发生了变化,那么就无法适用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了
  • 2.将查询分解后,执行单个查询可以减少锁的竞争
  • 3.再在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展
  • 4.查询本身效率也可能会有所提升。这个例子中,使用IN()代替关联查询,可以让MySQL按照ID顺序进行查询,这可能比随机关联要更高效。
  • 5.可以减少冗余记录的查询。在应用层做关联查询,意味着对于某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复地访问一部分数据。从这点看,这样的重构还可能会减少网络和内存的消耗
  • 6.更进一步,这样做相当于在应用中实现了哈希关联,而不是使用MySQL的嵌套循环关联。某些场景哈希关联的效率要高很多。
    在很多场景下,通过重构查询将关联放到应用程序中将会更加高效,这样的场景有很多。比如,当应用能够方便地缓存单个查询的结果的时候、当可以将数据分不到不同的MySQL服务器上的时候、当能够使用IN()的方式代替关联查询的时候、当查询中使用同一个数据表的时候

查询执行的基础

在这里插入图片描述

当希望MySQL能够以更高效的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解这一点,很多查询优化工作实际上就是遵循一些原则让优化器能够按照预想的合理的方式运行。MySQL执行一个查询的过程。根据如图所示,我们可以看到当向MySQL发送一个请求的时候,MySQL到底做了些什么。

  • 1.客户端发送一条查询给服务器
  • 2.服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段
  • 3.服务器端进入SQL解析、预处理,再由优化器生成对应的执行计划
  • 4.MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询
  • 5.将结果返回给客户端

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

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

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

相关文章

Python魔法之旅-魔法方法(14)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

【Python】pyinstaller打包时添加详细信息

在要被打包的py文件同级目录新建version.txt&#xff0c;写入以下内容 # UTF-8 # # For more details about fixed file info ffi see: # http://msdn.microsoft.com/en-us/library/aa381058.aspx # VSVersionInfo(ffiFixedFileInfo(filevers(1, 4, 0, 5),prodvers(1, 4, 0, 5…

AIGC 011-SAM第一个图像分割大模型-分割一切!

AIGC 011-SAM第一个图像分割大模型-分割一切&#xff01; 文章目录 0 论文工作1论文方法2 效果 0 论文工作 这篇论文介绍了 Segment Anything (SA) 项目&#xff0c;这是一个全新的图像分割任务、模型和数据集。SA 项目是一个具有里程碑意义的工作&#xff0c;它为图像分割领域…

迎七一党史知识竞赛答题怎么做

迎七一党史知识竞赛答题&#xff0c;不仅是对于党史知识的检验&#xff0c;更是对于参赛者学习态度和综合能力的考量。在参与这类竞赛时&#xff0c;我们需要做好充分的准备&#xff0c;掌握一定的答题技巧&#xff0c;才能取得好的成绩。 首先&#xff0c;我们要深入了解竞赛…

FFmpeg播放器的相关概念【1】

播放器框架 相关术语 •容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒体文件&#xff0c;比如mp4、flv、mkv等。 • 媒体流&#xff08;Stream&#xff09;&#xff1a;表示时间轴上的一段连续数据&#xff0c;如一段声音数据、一段…

UFS Explorer Professional Recovery: 如何从启用了 mSATA 缓存的 Drobo 设备中恢复数据

天津鸿萌科贸发展有限公司是 UFS Explorer Professional Recovery 数据恢复软件的授权代理商。 UFS Explorer Professional Recovery 数据恢复软件提供综合性的解决方案&#xff0c;用于解决复杂的数据恢复案例&#xff0c;包括那些采用特殊存储技术的案例&#xff0c;或介质受…

上海亚商投顾:创业板指震荡收涨 超70家ST股跌停

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡震荡&#xff0c;创业板指走势稍强&#xff0c;盘中一度涨超1%&#xff0c;黄白二线分化严重。算…

vue ts 导入 @/assets/ 红色显示的问题解决

vue ts 导入 /assets/ 红色显示的问题解决 一、问题描述 在使用的时候这样导入会出现如上的错误。 在使用的时候&#xff0c;导入的类型也没有对应的代码提示&#xff0c;说明导入有问题。 二、解决 在 tsconfig.json 中添加如下内容&#xff1a; {"compilerOptions&…

AI大模型探索之路-实战篇15: Agent智能数据分析平台之整合封装Tools和Memory功能代码

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…

46.ThreadPoolExcutor接口

线程池状态 ThreadPoolExcutor使用int高3位来表示线程池状态&#xff0c;低29位表示线程数量 状态高三位接收新任务处理阻塞队列任务说明RUNNING111YYSHUTDOWN000NY不会接收新任务&#xff0c;但会处理阻塞队列剩余任务&#xff0c;比较温和&#xff0c;已经提交的任务都会执…

C++ STL-迭代器函数对象适配器

目录 一.迭代器 二. 函数对象 三. 适配器 一.迭代器 是一种通用的指针类型&#xff0c;可以用来遍历 STL 容器中的元素。 具有以下作用和意义&#xff1a; 提供一种通用的方式来访问容器中的元素。允许对不同类型的容器进行统一的操作。增强了代码的灵活性和可扩展性。 一…

【C++题解】1085 - 寻找雷劈数

问题&#xff1a;1085 - 寻找雷劈数 类型&#xff1a;for循环 题目描述&#xff1a; 把整数 3025 从中剪开分为 30 和 25 两个数&#xff0c;此时再将这两数之和平方&#xff0c;计算结果又等于原数。 (3025)(3025)55553025 &#xff0c;这样的数叫“雷劈数”。 求所有符合这…

Photoshop版本选择及系统要求

1、ps2018cc/2020cc版本 适合新手&#xff0c;增加了很多智能化操作&#xff0c;非常方便好上手。 2020&#xff1a; 2、ps2015版本 cc2015版本不论是功能还是硬件上&#xff0c;都是不二选择&#xff0c;适合于配置较低的电脑&#xff0c;该有的基本功能它都有。 3、2021/2…

std::numeric_limits::max和宏定义重复报错问题

问题描述 今天在编译Beckhoff ADS开源组件的时候发现编译报错&#xff0c;报错代码如下 long AdsDevice::ReadReqEx2(uint32_t group, uint32_t offset, size_t length, void* buffer, uint32_t* bytesRead) const {if (length > std::numeric_limits<uint32_t>::ma…

Algorand 的复兴之路:改变游戏规则,打造 RWA 第一公链

TLDR 发布 AlgoKit 2.0&#xff0c;支持 Python 原生语言&#xff0c;打造开发者友好的开发环境&#xff0c;Algorand 的开发者社区规模迅速扩大。 升级共识激励机制&#xff0c;用 ALGO 奖励共识节点参与共识的执行&#xff0c;增加 ALGO 的应用场景&#xff0c;同时进一步确…

如何从官网下载 mysql 二进制安装包

一.下载二进行包 1. 官网网址: https://www.mysql.com/ 如图所示进入官网 2. 点击 DOWNLOADS ,进入如下图 在该页面找到 MySQL Community (GPL) Downloads 点进去 如上图页面&#xff0c;找到 MySQL Community Server 在点进去 下载 linux 通用版 点击最下面 Compressed …

(十四)统计学基础练习题八(选择题T351-400)

本文整理了统计学基础知识相关的练习题&#xff0c;共50道&#xff0c;适用于想巩固统计学基础或备考的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-统计学三&#xff09;。序号之前的题请看往期文章。 351&#xff09; 352&#xff09; 353&#xff09; 3…

Jmeter实战教程入门讲解

前言 通过前面对Jmeter元件的讲解&#xff0c;大家应该都知道常用元件的作用和使用了。编写Jmeter脚本前我们需要知道Jmeter元件的执行顺序&#xff0c;可以看看我这篇性能测试学习之路&#xff08;三&#xff09;—初识Jmeter来了解下。下面我将以工作中的一个简单的实例带大…

企业打款验证API在Java、Python、PHP中的使用教程

随着企业银行账号数量的增加和银行间的连接方式不断丰富&#xff0c;企业在进行资金交易时需要确保所填写的收款方账户信息的准确性和合法性&#xff0c;以避免资金损失和风险。然而&#xff0c;由于银行数量众多、地域分布广泛&#xff0c;不同银行间的账户验证机制和信息交互…

vue前端实现页面禁止缩放 前端适配问题处理 前端项目多端适配解决方案

在前端项目中,如果一个系统页面可以缩放可能会导致多种异常情况,这些异常情况涉及到页面布局、元素尺寸、事件触发、响应式设计和用户体验等方面。 1.布局错乱:页面元素在缩放后可能会出现错位、重叠或部分隐藏的情况,导致页面布局混乱,影响用户对页面内容的理解和操作。这…