MySQL之性能分析和系统调优

MySQL之性能分析和系统调优

性能分析

查看执行计划 EXPLAIN

EXPLAIN作为MySQL的性能分析神器,可以用来分析SQL执行计划,需要理解分析结果可以帮助我们优化SQL

explain selectfrom[where ...]

TABLE

表名 查询的每一行记录都对于着一张表

id

该语句的唯一标识。如果explain的结果包括多个id值,则数字越大越先执行;而对于相同id的行,则表示从上往下依次执行。

select_type

每一个子查询在语句中扮演的角色

  • simple: 不包含union或者子查询的语句
  • primary :最外层的查询
  • union: union中第二个后随后的select被标记为union;如果union被from子句中的子查询包含,那么它的第一个select会被标记为derived
  • dependent union: union中第二个或后面的的查询依赖了外面的查询
  • subquery: 子查询的第一个select
  • dependent subquery: 子查询的第二个或后面的select 依赖了外面的查询
  • derived :表示包含在from子句的子查询中的select,MySQL会将执行结果放在一个临时表中;MySQL内部将其称为derived table,因为该表是从临时查询中派生出来的
  • materialized:将子查询物化之后供外层连接使用

partitions

当前查询匹配记录的分区

type

执行查询时的访问方法

  • system:表中只有一个数据并且使用的存储引擎的统计数据是精确的,有一个变量记录(比如myisam memory)

  • const:根据主键或者唯一的二级索引列等值匹配时

  • eq_ref:被驱动表是通过主键或者唯一的二级索引进行匹配的

  • ref:普通的二级索引进行等值匹配

  • ref_or_null:该类型类似于ref,但是MySQL会额外搜索哪些行包含了NULL。这种类型常见于解析子查询

  • index_merge:此类型表示使用了索引合并优化,表示一个查询里面用到了多个索引

  • unique_subquery:该类型和eq_ref类似,但是使用了IN查询,且子查询是主键或者唯一索引

  • index_subquery:和unique_subquery类似,只是子查询使用的是非唯一索引

  • range:范围扫描,表示检索了指定范围的行,主要用于有限制的索引扫描

  • index:全索引扫描,和ALL类似,只不过index是全盘扫描了索引的数据

    查询仅使用索引中的一部分列时,可使用此类型。有两种场景会触发:

    • 如果索引是查询的覆盖索引,并且索引查询的数据就可以满足查询中所需的所有数据,则只扫描索引树。此时,explain的Extra 列的结果是Using index。index通常比ALL快,因为索引的大小通常小于表数据。
    • 按索引的顺序来查找数据行,执行了全表扫描。此时,explain的Extra列的结果不会出现Uses index。
  • all:全表扫描,性能最差

possible_keys

展示当前查询可以使用哪些索引,这一列的数据是在优化过程的早期创建的,因此有些索引可能对于后续优化过程是没用的。

key

表示MySQL实际选择的索引

key_len

索引使用的字节数。由于存储格式,当字段允许为NULL时,key_len比不允许为空时大1字节
主要针对联合索引,是否充分利用索引

ref

表示将哪个字段或常量和key列所使用的字段进行比较。

如果ref是一个函数,则使用的值是函数的结果。要想查看是哪个函数,可在EXPLAIN语句之后紧跟一个SHOW WARNING语句。

rows

MySQL估算会扫描的行数,数值越小越好。

filtered

表示符合查询条件的数据百分比,最大100。用rows × filtered可获得和下一张表连接的行数。例如rows = 1000,filtered = 50%,则和下一张表连接的行数是500。

extra

  • no tables used:没有from子句
  • impossible where:where始终为false
  • using where:不使用索引;使用索引但包含不使用索引的条件
  • no match min/max:使用聚合函数但没有匹配的where、
  • using index:查询到数据使用二级索引不需要进行回表操作;如果进行回表则是null
  • using index condition:Index condition pushdown索引条件下推

EXPLAIN格式

  • 传统格式:缺少一个衡量执行计划好坏的重要信息–成本
  • JSON格式:在explain和语句之间加上format=JSON 多一些详细信息如成本
  • TREE格式:在8.0.16新增格式 主要由各部分之间的关系和执行顺序决定
  • 可视化输出:workbench

show warmings

展示真实执行的sql语句

数据库设计规范

数据库主键的设计

自增ID

自增ID的问题(缺点太多)核心业务不推荐使用

1.可靠性不高,在集群模式下存在自增ID回溯的问题

2.安全性不高,容易被被爬虫获取数据

3.性能差,需要占用数据库服务端的资源(有AUTO-INC锁来完成)

4.交互多

5.局部唯一性(在一台机器下)

业务字段

与业务有关的字段不能设计为主键,对于数据库维护造成很大困难

UUID

优点:性能高;不依赖网络;使用简单;全局唯一

缺点:占用36个字节,长度过长,没有含义,无序

有序UUID

将时间高位和地位互换,这样时间保证了单调递增,去掉无用‘-’并使用二进制存储

雪花算法

时间戳(数据单调递增)+数据中心ID+机器编码(全局唯一性)+序列号(1ms内生成多个ID的问题)

缺点:

依赖了机器ID的分配,集群的扩容和缩容需要重新分配,可能会导致ID重复

(解决:可以使用zookeeper的临时顺序节点分配ID)

依赖了系统时间,如果集群中的机器时间被回拨,也可能造成ID重复

(解决:一个客户端:在取到新ID后与之前最大的ID比较,如果ID变小则报错或者等待)

(集群:美团的leaf每次有新节点接入zk时会将节点上报的时间和集群平均的时间对比,如果新加入的节点的时间落后于平均时间则报错)

范式

1NF

确保每一个字段的值都有原子性,属性的原子性有主观性(字段不可再分)

2NF

得有主键,且非主键字段必须完全依赖于主键,不能只依赖主键的一部分

一个表只表达一个意思

如果不完全依赖候选键会导致

1.数据冗余(重复数据记录多次)

2.插入异常

3.删除异常

4.更新异常

应该将表拆分直到满足2NF

3NF

非主键字段不能依赖于其他非主键字段(非主键字段之间相互独立)不存在传递性

反范式化

遵循业务优先的原则,为了减少关联查询可以适当增加冗余字段来增强读性能,以空间换时间

一个表中的字段修改那么也应该同步修改另一张表,保证数据一致性

适用场景

增加的冗余字段不需要经常进行修改,查询的时候不可或缺

SQL语句调优

逻辑查询优化

关联查询优化

联接算法

联接算法是MySQL数据库用于处理联接的物理策略。目前MySQL数据库仅支持Nested-Loops Join算法。

两张表的Join的过程:

在这里插入图片描述

上图的Fetch阶段是指当内表关联的列是辅助索引时,但是需要访问表中的数据,那么这时就需要再访问主键索引才能得到数据的过程,不论表的存储引擎是InnoDB存储引擎还是MyISAM,这都是无法避免的,只是MyISAM的回表速度要快点,因为其辅助索引存放的就是指向记录的指针,而InnoDB存储引擎是索引组织表,需要再次通过索引查找才能定位数据。

Fetch阶段也不是必须存在的,如果是聚集索引联接,那么直接就能得到数据,无需回表,也就没有Fetch这个阶段。另外,上述给出了两张表之间的Join过程,多张表的Join就是继续上述这个过程。

接着计算两张表Join的成本,这里有下列几种概念:

外表的扫描次数,记为O。通常外表的扫描次数都是1,即Join时扫描一次外表(驱动表)的数据即可

内表的扫描次数,记为I。根据不同Join算法,内表(被驱动表)的扫描次数不同

读取表的记录数,记为R。根据不同Join算法,读取记录的数量可能不同

Join的比较次数,记为M。根据不同Join算法,比较次数不同

回表的读取记录的数,记为F。若Join的是辅助索引,可能需要回表取得最终的数据

  • Simple Nested-Loops Join(SNLJ,简单嵌套循环联接)

没有索引,小表驱动大表;暴力循环查找

  • Index Nested-Loops Join(INLJ,基于索引的嵌套循环联接)

在内表建立索引,以此降低Nested-Loop Join算法的开销,减少内表扫描次数

外连接消除

我们前边说过,内连接的驱动表和被驱动表的位置可以相互转换,而左(外)连接和右(外)连接的驱动表和被驱动表是固定的,因为有些不满足联接条件的记录会通过外部表行的方式再次添加到结果中。这就导致内连接可以通过优化表的连接顺序来降低整体的查询成本,而外连接却无法优化表的连接顺序。

外连接和内连接的本质区别就是:对于外连接的驱动表的记录来说,如果无法在被驱动表中找到匹配ON子句中的过滤条件的记录,那么该记录仍然会被加入到结果集中,对应的被驱动表记录的各个字段使用NULL值填充;而内连接的驱动表的记录如果无法在被驱动表中找到匹配ON子句中的过滤条件的记录,那么该记录会被舍弃。

  • Block Nested-Loops Join(BNL,基于块的嵌套循环联接)

引入join buffer缓冲区不是一次一条取驱动表数据而是一块一块取减少IO次数,在8.0.2版本被hash join替代

整体效率:INLJ>BNLJ>SNLJ

优化策略

1.用小的结果集驱动大的结果集

2.为被驱动表的匹配条件字段增加索引减少内层循环次数

3.使用BNLJ时可以适当增大join buffer的大小

4.hash join大数据连接时常用方式:优化器使用较小的表的join key在内存中建立散列表,通过扫描较大的表并探测散列表找出匹配的行

子查询优化

子查询可以帮准我们通过一个SQL来实现较为复杂的的查询但子查询的效率一般都不高

缺点:

1.执行子查询时内层查询会建立一个临时表,撤销临时表都会消耗资源产生大量慢查询

2.产生的临时表没有索引,效率低

建议:使用连接查询JOIN来代替子查询

排序优化

可以通用filesort和index两种方式排序

index :通过有序索引顺序扫描直接返回有序数据,不需要额外的排序,操作效率较高。

filesort:通过对返回数据进行排序,filesort 并不代表通过磁盘文件排序,而是说明进行了一个排序操作,至于排序操作是否使用了磁盘文件或临时表等,则取决于MySQL服务器对排序参数的设置和需要排序数据的大小。

有两种排序算法:

1.双路排序算法:从磁盘取排序的字段,在buffer中排序后再从磁盘中取排好序的数据

2.单路排序算法:从磁盘读取所有需要排序字段的排序数在buffer中排好序输出,内存空间占用大,sort_buffer_size适当调大

sort_buffer_size设置的排序区是每个线程独占的,所以同一时刻,MySQL中存在多个sort buffer排序区。

GROUP BY优化

先排序再分组 遵循最佳左前缀原则

无法使用索引列时增加sort_buffer_size和max_length_for_sort_data

where效率高于having

减少使用order by尽量在客户端进行数据排序,数据库的CPU资源是宝贵的

使用覆盖索引和索引下推

(在索引篇已经说明)

物理查询优化

索引优化

sql语句是否使用索引与优化器的选择有关(数据库版本,数据量,数据选择度),不基于语义,也不基于规则,而是基于const开销

什么会导致索引失效

>、<范围查询(一般将范围查询条件放在最后)

mysql 会一直向右匹配直到遇到索引搜索键使用>、<就停止匹配。一旦权重最高的索引搜索键使用>、<范围查询,那么其它>、<搜索键都无法用作索引。即索引最多使用一个>、<的范围列,因此如果查询条件中有两个>、<范围列则无法全用到索引。

like %xx

如搜索键值以通配符%开头(如:like '%abc'),则索引失效,直接全表扫描;若只是以%结尾,则不影响索引构建

类型转换导致索引失败

如果列是字符串类型,传入条件是必须用引号引起来,不然报错或索引失效

计算或者函数导致索引失效

如果查询条件中含有函数或表达式,将导致索引失效而进行全表扫描

不等于索引失效情况

普通索引使用 !=索引失效,主键索引没影响。
where语句中索引列使用了负向查询,可能会导致索引失效。
负向查询包括:NOT、!=、<>、NOT IN、NOT LIKE等。

or 条件索引问题

or 的条件列除了同时是主键的时候,索引才会生效。其他情况下的,无论条件列是什么,索引都失效。

联合索引违背最左匹配原则

联合索引中,where中索引列违背最左匹配原则,一定会导致索引失效

其他优化策略

exists和in的区别

主要由表的大小决定,in适合用于驱动表比被驱动表小的情况,exists适合用于驱动表比被驱动表大的情况

count*和count(具体字段)的区别

如果是myisam存储引擎,在每一张表都有一个row_count字段存储表数据行数,那么查询数据行数的时间复杂度是o(1)的,但由于InnoDB中支持行级锁和MVCC机制,无法维护这样的变量,所以是全表扫描时间复杂度是o(n)的

count(具体字段)一般推荐使用二级索引,因为二级索引存储的字段更小count(*)和count(1)一般自动选择key_length小的索引

关于select*

mysql中将*通过查询数据字段转变为对应的字段需要花费时间和资源

不能使用覆盖索引

limit 1

对于会进行全表扫描的sql,如果我们确定结果集只有一个,那么加上limit 1后查询到一条数据后就不会再进行查询,加快查询速度

但是如果针对已经是唯一索引的字段就没有必要了

多使用commit

commit会释放相应的资源

1.回滚段记录的用于恢复数据

2.被程序获得的锁

3.redo/undo log buffer中的空间

4.管理上述资源花费的资源

数据库其他调优

选择合适的DBMS

如果对数据安全性以及事务性处理要求高的话可以使用SQL Server或者Oracle

选择合适的存储引擎,innodb支持事务,行锁外键等,适用于事务性要求高,myisam处理大量的更新操作

优化表的设计

表要求遵循第三范式

如果查询应用较多,进行的大量的多表查询操作,可以将经常查询的字段增加来换取查询的效率也是反范式化

表的字段类型的选择

优化查询逻辑

逻辑查询优化:改变SQL语句的内容让SQL执行更高效

物理查询优化:索引优化

使用Redis作为缓存

库级优化

读写分离

数据分片,对数据库分库分表

优化MySQL服务器

服务器硬件优化

优化数据库结构

拆分表:冷热数据的分离(一个页中可以存储更多数据减少磁盘IO)

增加中间表

增加冗余字段(反范式化)

优化数据类型:
1.比如对于非负型整数可以使用unsigned来存储

2.对于文本数据类型大整数占用空间更少

3.避免使用text blog,MySQL内存临时表不支持,必须使用磁盘临时表,性能差

4.避免使用enum,修改enum需要使用alter语句,尽量用tinyint来替代

5.使用timestamp

6.使用decimal避免float double

优化插入记录的速度

myisam:

1.禁用索引

2.禁用唯一性

3.检查使用批量插入

innodb:

1.禁用唯一性检查

2.禁用外键检查

3.禁止自动提交

使用非空约束
分析表检查表优化表

分析表:ANALYZE 分析表各个字段

检查表:CHECK

优化表:OPTIMIZE

大表优化

限定查询范围

读写分离

垂直拆分 分库分表 水平拆分

其他调优策略

服务器语句超时处理

创建全局通用表空间

隐藏索引

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

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

相关文章

干了3年功能测试,技术回到原点

简单概括一下 先说一下自己的情况&#xff0c;普通本科&#xff0c;18年通过校招进入深圳某软件公司&#xff0c;干了3年多的功能测试&#xff0c;21年的那会&#xff0c;因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不…

推荐一款优秀的json在线格式化校验工具

www.bjson.chat 这个工具是目前见过最好用的JSON工具&#xff0c; 页面简单&#xff0c;支持text&#xff0c;tree两种显示格式&#xff0c;关键词高亮显示支持亮白和暗黑两种风格最主要的是如果要格式化很长的json的话&#xff0c;这个工具还可以全屏显示&#xff0c;简直不…

非标设计之螺纹选型

目录 一、螺纹种类二、 螺纹加工&#xff1a;第一大类&#xff1a;螺纹切削第二大类&#xff1a;螺纹滚压三、螺丝钻孔和选型&#xff1a; 一、螺纹种类 一、螺纹种类 按牙型可分为三角形、梯形、矩形、锯齿形和圆弧螺纹&#xff1b; 按螺纹旋向可分为左旋和右旋&#xff1b;…

电脑如何录音?适合初学者的详细教程

“电脑怎么录音呀&#xff1f;参加了一个学校举办的短视频大赛&#xff0c;视频拍摄都很顺利&#xff0c;音乐却出了问题&#xff0c;朋友说可以用电脑录制一段音乐应付一下&#xff0c;可是我不会操作&#xff0c;有哪位大佬教教我&#xff01;” 声音是一种强大的媒介&#…

七天.NET 8操作SQLite入门到实战 - 第五天引入SQLite-net ORM并封装常用方法(SQLiteHelper)

前言 上一章节我们搭建好了EasySQLite的前后端框架&#xff0c;今天我们的主要任务是在后端框架中引入SQLite-net ORM并封装常用方法&#xff08;SQLiteHelper&#xff09;。 七天.NET 8操作SQLite入门到实战详细教程 第一天 SQLite 简介第二天 在 Windows 上配置 SQLite环境…

C语言每日一题(43)旋转链表

力扣 61 旋转链表 题目描述 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3]示例 2&#xff1a; 输入&#xff1a;head [0,1,2], …

⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)

1.这里我代码没啥问题~~~编辑器里也没毛病 void Start(){// 加载底图和上层图片string backgroundImagePath Application.streamingAssetsPath "/background.jpg";Texture2D backgroundTexture new Texture2D(2, 2);byte[] backgroundImageData System.IO.File.R…

永恒之蓝漏洞复现

网安2211-202221336029 目录 1.介绍&#xff1a; 2.操作&#xff1a; 1.实验环境&#xff1a; 2.渗透实现 3.实现后操作 3.总结&#xff1a; 1.介绍&#xff1a; 1.漏洞描述&#xff1a;Eternalblue通过TCP端口445和139来利用SMBv1和NBT中的远程代码执行漏洞&#xff0…

【无标题】mmocr在云服务器上

这里写目录标题 1、创建虚拟环境2、切换和退出conda虚拟环境3. 显示、复制&#xff08;克隆&#xff09;、删除虚拟环境4、删除环境安装指示中 cd进项目文件夹开始训练模型&#xff08;python XXX.py | tee record.txt 记录训练结果&#xff09;如何在Linux服务器上安装Anacond…

数据结构--->单链表

文章目录 链表链表的分类 单链表单链表的存储结构单链表主要实现的接口函数单链表尾插动态申请新节点单链表头插单链表的尾删单链表的头删在指定位置之前插入单链表查找插入 在指定位置之后插删除指定位置元素删除指定位置之后的元素顺序输出链表销毁单链表 顺序表和单链表的区…

Redis主从与哨兵架构详解

目录 主从架构 主从环境搭建 主从复制流程 1. 全量复制 2. 部分复制 主从风暴 哨兵架构 概念 哨兵环境搭建 主从架构 主从环境搭建 1. 复制一份redis.conf文件, 修改下面几行配置 port 6380 pidfile /var/run/redis_6380.pid logfile "6380.log" dir /usr/…

基于A*的网格地图最短路径问题求解

基于A*的网格地图最短路径问题求解 一、A*算法介绍、原理及步骤二、Dijkstra算法和A*的区别三、A*算法应用场景四、启发函数五、距离六、基于A*的网格地图最短路径问题求解实例分析完整代码 七、A*算法的改进思路 一、A*算法介绍、原理及步骤 A*搜索算法&#xff08;A star al…

PCB走线宽度与电流的关系表

在1 oz./sq. ft.铜重量时将温度上升限制在10C。这应该可以让您大致了解如何调整PCB中的走线尺寸。 电流&#xff08;A&#xff09;走线宽度&#xff08;mil&#xff09;1102303504805110615071808220926010300 上表适用于许多通常采用标准工艺生产的PCB&#xff0c;其目标是非…

Python按要求从多个txt文本中提取指定数据

基本想法 遍历文件夹并从中找到文件名称符合我们需求的多个.txt格式文本文件&#xff0c;并从每一个文本文件中&#xff0c;找到我们需要的指定数据&#xff0c;最后得到所有文本文件中我们需要的数据的集合 举例 如现有名为file一个文件夹&#xff0c;里面含有大量的.txt格…

【数据库】数据库并发控制的目标,可串行化序列的分析,并发控制调度器模型

数据库并发控制 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定期更…

【稳定检索|投稿优惠】2024年生物神经工程与健康大数据国际会议(ICBNHBD 2024)

2024年生物神经工程与健康大数据国际会议(ICBNHBD 2024) 2024 International Conference on Biological Neuroengineering and Health Big Data(ICBNHBD) 一、【会议简介】 2024年生物神经工程与健康大数据国际会议(ICBNHBD 2024)&#xff0c;这场科学盛宴&#xff0c;会议在中…

LeetCode刷题---汉诺塔问题

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 前言&#xff1a;这个专栏主要讲述递归递归、搜索与回溯算法&#xff0c;所以下面题目主要也是这些算法做的 我讲述题目会把讲解部分分为3个部分&#xff1a; 1、题目解析 2、算法原理思路讲解 …

webGL开发虚拟展览方案

开发 WebGL 虚拟展览涉及到选择适当的工具、技术和框架&#xff0c;以及设计一个令人愉悦且互动性强的用户体验。以下是一个可能的开发方案&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.选择 Web…

【C语言】与文件有关的操作

目录 1. 前言2. 什么是文件&#xff1f;2.1 程序文件2.2 数据文件2.3 文件名 3. 二进制文件和文本文件&#xff1f;4. 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭 5. 文件的顺序读写5.1 顺序读写函数介绍5.2 对比一组函数 6. 文件的…

对 Vision Transformers 及其基于 CNN-Transformer 的变体的综述

A survey of the Vision Transformers and its CNN-Transformer based Variants 摘要1、介绍2、vit的基本概念2.1 patch嵌入2.2 位置嵌入2.2.1 绝对位置嵌入(APE)2.2.2 相对位置嵌入(RPE)2.2.3卷积位置嵌入(CPE) 2.3 注意力机制2.3.1多头自我注意(MSA) 2.4 Transformer层2.4.1 …