从业务应用开发者的角度优化MySQL性能

MySQL的性能优化包括操作系统和硬件优化、MySQL服务配置优化、合理的表结构设计和索引设计、查询优化等等,其中业务应用开发者能做的主要在表结构、索引、查询三个方面,以下对这三个方面的优化思路做简单介绍。内容主要参考《高性能MySQL(第四版)》第六、七、八章,如无特别说明,以下优化内容主要针对InnoDB引擎和B-Tree索引。

表定义

选择优化的数据类型

简单够用,尽量避免NULL值。

  • 更小的通常更好:更小的数据类型占用的磁盘、内存和CPU缓存的空间更少,处理时需要的CPU周期也更少。但也要确保没有低估要存储的值的范围。

  • 简单为好:简单数据类型的操作通常需要的CPU周期更少。

  • 尽量避免存储NULL:可为NULL的列使得索引、索引统计和值比较都更复杂,对MySQL来说更难优化。可为NULL的列会使用更多的存储空间。

表结构设计的陷阱

  • 太多的列:非常宽的表CPU消耗非常严重

MySQL的存储引擎API通过在服务器和存储引擎之间以行缓存区格式复制行来工作;服务器将缓存区解码为列。将行缓存区转换为有解码列的行数据结构的操作代价非常高。InnoDB的行格式总是需要转换。这种转换的成本取决于列数。

  • 太多的联接:如果需要以高并发性快速执行查询,每个查询最好少于十几张表。

  • 谨慎但不要惧怕使用NULL:可以使用0、特殊值或空字符串作为空值代替NULL;但当使用NULL比其他替代方案更简单时,使用NULL也许会更好。

索引设计

三星索引

索引将相关的记录放到一起则获得“一星”;索引中的数据顺序和查找中的排序顺序一致则获得“二星”;索引中的列包含了查询中需要的全部列则获得“三星”。

高性能的索引策略

索引的选择性

索引的选择性是指,不重复的索引值/数据表的记录总数(#T)的比值,范围从1/#T到1之间。索引的选择性越高则查询效率越高。唯一索引的选择性是1。

前缀索引和索引的选择性

有时为了提升索引的性能同时节省索引空间,可以只对字段的前一部分字符进行索引,这样做的缺点是,会降低索引的选择性,并且无法使用覆盖索引的特性。

多列索引设计

设计索引的列顺序有一个重要的经验法则:将选择性最高的列放到索引最前。

为了借助索引完成排序和分组,就需要根据排序和分组的需求设计索引。

多列索引也需要兼顾使用其中的某一列筛选数据的情况,要注意最左匹配的要求。

覆盖索引

如果可以使用索引直接获取列的数据而不再需要读取数据行,那么这个索引就是覆盖索引。

利用索引扫描来做排序

MySQL有两种方式可以生成有序的结果:通过排序操作,或者按索引顺序扫描。

只有当索引的顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向(倒序或正序)都一样时,MySQL才能使用索引来对结果做排序。

ORDER BY子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求,否则,MySQL需要执行排序操作,而无法利用索引排序。

删除重复索引和冗余索引

重复索引:指在相同的列上按照相同顺序创建的相同类型的索引。

冗余索引:冗余索引和重复索引有一些不同。如果创建了索引(A,B),再创建索引(A)就是冗余索引,因为这只是前一个索引的前缀索引,因此,索引(A,B)也可以当作索引(A)来使用(这种冗余只是对B-tree索引来说的)。

重复索引和冗余索引的危害:MySQL要单独维护每个索引,包括重复和冗余索引,并且优化器在优化查询的时候也需要逐个地进行评估,这会影响性能,同时也浪费磁盘空间。

删除未使用的索引

在sys数据库中,在table_io_waits_summary_by_index_usage视图中可以查询到哪些索引从来没有被使用过。

更新索引统计信息

如果存储引擎向优化器提供的扫描行数信息不准确,或者执行计划本身太复杂以致无法准确地获取各个阶段匹配的行数,那么优化器会使用索引统计信息来估算扫描行数。MySQL的优化器使用的是基于成本的模型,而衡量成本的主要指标就是一个查询需要扫描多少行。如果表没有统计信息,或者统计信息不准确,优化器就很有可能做出错误的决定。可以通过运行ANALYZE TABLE来重新生成统计信息,以解决这个问题。

查询设计

性能优化思路:如果把查询看作一个任务,那么这个任务由一系列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,要么消除其中的一些子任务,要么减少子任务的执行次数,要么让子任务执行的更快。

查询的生命周期

从客户端到服务器,然后在服务器上进行语法解析,生成执行计划,执行,并返回给客户端。其中“执行”是整个生命周期中最重要的阶段,这其中包括大量为了检索数据对存储引擎的调用以及调用后的数据处理,包括排序、分组等。

优化数据访问

是否向数据库请求了不需要的数据

  • 查询了不需要的记录:比如分页查询中仅需要10条,却请求了100条数据

  • 多表联接时返回全部列,正确的做法是用到多少列返回多少列

  • 总是取出全部列,这种做法有好有坏:

    • 好处是SQL可能会复用

    • 坏处是无法使用覆盖索引,为服务器带来额外的I/O、内存、CPU消耗

  • 重复查询相同的数据。解决方式是把查询结果缓存起来

MySQL是否在扫描额外的记录

扫描行数和返回行数

分析MySQL在执行查询时扫描的行数和返回的记录数,在一定程度上能够评估该查询的效率高不高。理想情况下,扫描的行数和返回的记录数应该是相同的。

扫描的行数和访问类型

EXPLAIN语句中的type列反映了访问类型。访问类型有很多种,从全表扫描到索引扫描、范围扫描、唯一索引查询、常数引用等。以上类型速度从慢到快,扫描的行数从多到少。

重构查询方式

复杂查询拆分

考虑将一个复杂的查询分成多个简单的查询

分解联接查询

将联表查询拆分为单表查询

查询优化器的优化类型

了解查询优化器的优化类型,有助于写出对优化器更友好的语句,以下是常见的优化类型:

  • 重新定义联接表的顺序

  • 将外联接转化成内联接:有些外联接可以被转化为内联接,然后再通过调整内联接上各个表的联接顺序

  • 使用代数等价变换规则:MySQL使用一些代数等价变换规则来简化并规范表达式。例如,(5=5 AND a>5)将被改写为a>5。

  • 优化COUNT()、MIN()、MAX():如果某一列在B-tree索引上,那么在计算该列的最小值时,可以直接取索引最左端的记录。MAX()类似。

  • 索引覆盖扫描:直接使用索引返回需要查询的列数据。

  • 提前终止查询:在发现已经满足查询需求的时候,MySQL总是能立刻终止查询

  • 列表IN()的比较:MySQL中IN()查询比OR查询效率更高。MySQL将IN()列表中的数据先进行排序,然后通过二分查找的方式确定列表中的值是否满足条件,这是一个O(logn)复杂度的查询;而OR查询则是O(n)的复杂度。当IN()列表中有大量取值时,处理速度的提升会更明显

特定类型的优化

优化联接查询

  • 确保ON或者USING子句中的列上有索引。在创建索引的时候需要考虑联接的顺序。当表A和表B用列c联接的时候,如果优化器的联接顺序是B、A,那么就不需要在B表的对应列上建索引。

  • 确保任何GROUP BY和ORDER BY中的表达式只涉及一个表中的列,这样MySQL才有可能使用索引来优化这个过程。

优化分页查询

优化此类分页查询的一个最简单的办法就是尽可能地使用索引覆盖扫描,而不是查询所有的行。然后根据需要做一次联接操作再返回所需的列。在偏移量很大的时候,这样做的效率会有非常大的提升。

优化UNION查询

  • 子句下推:MySQL通过创建并填充临时表的方式执行UNION查询,因此很多在UNION结果的基础上执行的WHERE、LIMIT、ORDER BY子句无法做优化。可以将UNION结果后的WHERE、LIMIT、ORDER BY等子句“下推”到UNION的各个子查询中,以便优化器利用这些条件进行优化。

  • 使用UNION ALL代替UNION:除非明确需要在MySQL服务器上消除重复的行,否则一定要使用UNION ALL。如果没有ALL关键字,MySQL会给临时表加上DISTINCT选项,这会导致对整个临时表的数据做唯一性检查。这样做的代价非常高。

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

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

相关文章

如何解决Nginx启动出现闪退问题?

哈喽,大家好,我是小浪。那么大家首次在启动nginx的时候,绝大部分同学会出现以下情况,就是我们双击nginx.exe文件之后,屏幕闪退一下就没了,然后我们访问localhost:8080提示404. 那么出现这种情况其实是我们…

全面解析企业财务报表系列之一:企业经营者懂财务的重要性

全面解析企业财务报表系列之一:企业经营者懂财务的重要性 一、企业经营者懂财务的重要性二、如何通过数字展开经营 一、企业经营者懂财务的重要性 企业经营者不懂会计,就好像蒙着眼睛开车。而方向盘就是你的战略,刹车系统就是你的预算&#…

去重求和(最大N个数和最小N个数的和)(C 语言)

题目 给定一个数组,编写一个函数, 计算他的最大N个数和最小N个数的和, 需要对数组进行去重。 输入 第一行输入M,M表示数组大小 第二行输入M个数,表示数组内容 第三行输入N表示需要计算的最大最小N的个数 输出 输出…

NestJS入门7:增加异常过滤器

前文参考: NestJS入门1 NestJS入门2:创建模块 NestJS入门3:不同请求方式前后端写法 NestJS入门4:MySQL typeorm 增删改查 NestJS入门5:加入Swagger NestJS入门6:日志中间件 本文代码基于上一篇文章《…

深度学习基础(二)卷积神经网络(CNN)

之前的章节我们初步介绍了深度学习相关基础知识和训练神经网络: 深度学习基础(一)神经网络基本原理-CSDN博客文章浏览阅读924次,点赞13次,收藏19次。在如今的科技浪潮中,神经网络作为人工智能的核心技术之…

关于git子模块实践(一)

背景 在日常项目开发中,随着项目的迭代,不可避免的是主项目会引入到很多三方库,或者自研的一些模块。有一种场景,就是这些模块,是随着开发而进行迭代,且多个项目公用的,这种情况,在…

第3.3章:StarRocks数据导入——Stream Load

一、概述 Stream Load是StarRocks最为核心的导入方式,用户通过发送HTTP请求将本地文件或数据流导入至StarRocks中,其本身不依赖其他组件。 Stream Load支持csv和json两种数据文件格式,适用于数据文件数量较少且单个文件的大小不超过10GB 的场…

v-rep插件

v-rep官网插件汉化教程 官网教程 插件是什么 插件本质上就是遵循一定规范的API编写出来的程序,在v-rep中最终需要编译为动态库。 linux下是libsimXXXX.so; 其中XXXX是插件的名称。 请至少使用4个字符,并且不要使用下划线,因为…

kafka生产者2

1.数据可靠 • 0:生产者发送过来的数据,不需要等数据落盘应答。 风险:leader挂了之后,follower还没有收到消息。。。。 • 1:生产者发送过来的数据,Leader收到数据后应答。 风险:leader应答…

【机器学习】数据清洗——基于Numpy库的方法删除重复点

🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:机器学习 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进…

解锁网络潜能:深入探索SCTP及其在现代通信中的革命性作用

第一部分:SCTP简介 流控制传输协议(SCTP)是一种传输层协议,设计用于支持Internet上的多路径消息传输。它结合了TCP的可靠性和UDP的简洁性,提供了多种高级特性,如多宿(multi-homing)…

解释Iterable和Iterator接口

在Java中,Iterable和Iterator是两个重要的接口,它们在集合框架中扮演着核心的角色,尤其是在遍历集合元素的时候。 Iterable接口 Iterable接口是Java Collections Framework的一部分,位于java.lang包中。任何实现了Iterable接口的…

PostgreSQL索引篇 | BTree

B-Tree索引 (本文为《PostgreSQL数据库内核分析》一书的总结笔记,需要电子版的可私信我) B树特点: 非叶子节点含一个或多个关键字值和子节点指针,不指向实际数据的存储位置所有关键字都是叶子节点,每个叶…

Python运算符你学会了吗?

1.算术运算符 (加)、-(减)、*(乘)、/(除)、%(取余)、//(取整)、**(求幂) a 12 b 3 c 7print(a b) # 15 …

关于Kinect 互动沙盘 深度图 Shader Graph 分层

把Kinect的深度图穿给Shader Graph using com.rfilkov.kinect; using UnityEngine; using UnityEngine.UI; public class GetDepthTex : MonoBehaviour { public Material Mat_SandTable; void Update() { Mat_SandTable.SetTexture("_MainTex"…

【openGL教程08】关于着色器(02)

LearnOpenGL - Shaders 一、说明 着色器是openGL渲染的重要内容,客户如果想自我实现渲染灵活性,可以用着色器进行编程,这种程序小脚本被传送到GPU的显卡内部,起到动态灵活的着色作用。 二、着色器简述 正如“Hello Triangle”一章…

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(二)

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(二) 大家好 我是寸铁👊 金三银四,树、dfs、bfs、回溯、递归是必考的知识点✨ 快跟着寸铁刷起来!面试顺利上岸👋 喜欢的小伙伴可以点点关注 💝 上期回顾 感谢大家的支持&am…

简单的单层感知机(Perceptron)模型

[‘您需要实现一个简单的单层感知机(Perceptron)模型,并提供对其训练方法的实现。单层感知机是一种基础的线性二分类器,它对输入向量进行权值组合,然后通过激活函数(通常是一个符号函数)来决定该…

[附完整代码]群智能算法跑21种真实世界优化问题,并输出结果到excel||群智能算法跑CEC 2020真实世界优化问题,并输出结果到excel

1、简介 灰狼算法跑跑21种真实世界优化问题|足球训练队优化算法跑21种真实世界优化问题||牛顿拉夫逊算法跑21种真实世界优化问题||冠状豪猪CPO跑21种真实世界优化问题。 ‘FTTA’,‘BWO’, ‘CPO’, ‘FHO’, ‘GWO’, ‘HHO’, ‘NRBO’,‘SCA’,‘SGA’,WOA’跑21种真实世…

拓扑矩阵是四维协变量吗?

* 现在需要明确,拓扑矩阵的维度高于链表数据,那么用矩阵就可以控制链表数据,用矩阵表来 * 做循环,四维循环相当于三维向量的矢量运动嘛?我们在矩阵上面做计算也可以启动链表的运 * 动控制模型。。 * * 四维算法中应…