10.从架构师角度理解MySQL性能优化和索引合并

news2024/11/27 12:59:01

MySQL性能调优

  • 1. 查询性能优化
    • 1.1 什么是慢查询
    • 1.2 慢查询的配置
    • 1.3 慢查询解读分析
      • 1.3.1 日志模式
      • 1.3.2 慢查询分析
        • mysqldumpshow
    • 1.4 优化SQL查询方法论
      • 1.4.1 业务层--请求了不需要的数据?
        • 查询不需要的记录
        • 总是取出全部列
        • 重复查询相同的数据
      • 1.4.2 执行层--是否在扫描额外的记录
        • 响应时间
        • 扫描的行数和返回的行数
        • 扫描的行数和访问的类型
    • 1.5 重构SQL查询的方法论
      • 1.5.1 一个复杂查询还是多个简单查询
      • 1.5.2 切分查询
      • 1.5.3 分解关联查询
    • 1.6 从MySQL执行全流程考虑性能优化
      • 1.6.1 为什么查询速度会慢
      • 1.6.2 查询执行的流程再回顾
      • 1.6.3 MySQL客户端/服务端通信
      • 1.6.4 生命周期中的查询优化处理
      • 1.6.5 查询执行引擎
      • 1.6.6 返回结果给客户端
      • 1.6.7 查询状态
      • 1.6.8 通过show profile分析SQL
        • show processlist
        • 通过show profile分析

本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。

MySQL性能优化其实是个很大的课题,在优化上存在着一个调优金字塔的说法:

在这里插入图片描述

很明显从图上可以看出,越往上走,难度越来越高,收益却是越来越小的。比如硬件和 OS调优,需要对硬件和OS有着非常深刻的了解,例如磁盘阵列 (RAID)级别、是否可以分散磁盘IO、是否使用裸设备存放数据,使用哪种文件系统,还有操作系统的调度算法等等。

所以在进行优化时,首先需要关注和优化的应该是架构,如果架构不合理,即使是DBA 能做的事情其实是也是比较有限的。

对于架构调优,在系统设计时首先需要充分考虑业务的实际情况,是否可以把不适合数 据库做的事情放到数据仓库、搜索引擎或者缓存中去做;然后考虑写的并发量有多大, 是否需要采用分布式;最后考虑读的压力是否很大,是否需要读写分离。对于核心应用或者金融类的应用,需要额外考虑数据安全因素,数据是否不允许丢失。

对于MySQL调优,需要确认业务表结构设计是否合理,SQL语句优化是否足够,该添加的索引是否都添加了,是否可以剔除多余的索引等等。

最后对于系统、硬件上的调优系统瓶颈在哪里,哪些系统参数需要调整优 化,进程资源限制是否提到足够高;在硬件方面是否需要更换为具有更高I/O性能的存储硬件,是否需要升级内存、CPU、网络等。
知道了调优的方向,下面还是主要从mysql角度去优化。

1. 查询性能优化

1.1 什么是慢查询

慢查询日志,顾名思义,就是查询慢的日志,是指mysql记录所有执行超过long_query_time参数设定的时间阈值的SQL语句的日志。该日志能为SQL语句的优化带来很好的帮助,默认情况下,慢查询日志是关闭的,要使用慢查询日志功能,首先要开启慢查询日志功能。

优化数据访问方法论

  • 业务层-请求了不需要的数据?
    • 查询不需要的记录
    • 总是取出全部列重复
    • 查询相同的数据
  • 执行层-是否在扫描额外的记录?
    • 响应时间
    • 扫描的行数和返回的行数
    • 扫描的行数和访问类型

1.2 慢查询的配置

我们已经知道慢查询日志可以帮助定位可能存在问题的SQL语句,从而进行SQL语句层面的优化。但是默认值为关闭的OFF,需要我们手动开启ON:

show VARIABLES like 'slow_query_log';

在这里插入图片描述

开启:

set GLOBAL slow_query_log=1;

在这里插入图片描述

但是多慢算慢?MySQL中可以设定一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询日志中。long_query_time参数就是这个阈值。默认值为10,代表10秒。

show VARIABLES like '%long_query_time%';

在这里插入图片描述

当然也可以设置

set global long_query_time=0;---默认10秒,这里为了演示方便设置为0

设置成0秒的意思是我所有的sql语句都放到这个慢查询日志中去。

同时对于没有运行的SQL语句没有使用索引,则 MySQL数据库也可以将这条SQL语句记录到慢查询日志文件,控制参数是:

show VARIABLES like '%log_queries_not_using_indexes%";

在这里插入图片描述

对于产生的慢查询日志,可以指定输出的位置,通过参数 log_output来控制,可以输出到[TABLE][FILE][FILE,TABLE]。比如

set global log_output='FILE,TABLE'

缺省是输出到文件,我们的配置把慢查询输出到表,不过一般不推荐输出到表。

show VARIABLES like 'log_output';ls

在这里插入图片描述

1.3 慢查询解读分析

1.3.1 日志模式

开启慢查询功能以后,会根据我们的配置产生慢查询日志

在这里插入图片描述

从慢查询日志里面摘选一条慢查询日志,数据组成如下

“Time: 2021-04-05T07:50:53.243703Z”:查询执行时间

“User@Host: root[root] @ localhost [] Id: 3”:用户名 、用户的IP信息、线程ID号

“Query_time: 0.000495”:执行花费的时长【单位:秒】

“Lock_time: 0.000170”:执行获得锁的时长

“Rows_sent”:获得的结果行数

“Rows_examined”:扫描的数据行数

“SET timestamp”:这SQL执行的具体时间

最后一行:执行的SQL语句

1.3.2 慢查询分析

慢查询的日志记录非常多,要从里面找寻一条查询慢的日志并不是很容易的事情,一般来说都需要一些工具辅助才能快速定位到需要优化的SQL语句,下面介绍两个慢查询辅助工具:一个是mysqldumpshow,另一个直接在百度里面输入:pt-query-digest安装即可

mysqldumpshow

常用的慢查询日志分析工具,汇总除查询条件外其他完全相同的SQL,并将分析结果按照参数中所指定的顺序输出。当然它的参数不少,我们常用的也就是那么几个。

语法:

mysqldumpslow -s r -t 10 slow-mysql.log

-s order (c,t,l,r,at,al,ar)

c:总次数

t:总时间

l:锁的时间

r:获得的结果行数

at,al,ar :指t,l,r平均数 【例如:at = 总时间/总次数】

-s 对结果进行排序,怎么排,根据后面所带的 (c,t,l,r,at,al,ar),缺省为at

-t NUM just show the top n queries:仅显示前n条查询

-g PATTERN grep: only consider stmts that include this string:通过grep来筛选语句。

./mysqldumpslow -s t -t 10 /home/mysql/mysql57/data/iZwz9j203ithc4gu1uvb2wZ-slow.log

在这里插入图片描述

./mysqldumpslow -s t -t 10 /home/mysql/mysql57/data/iZwz9j203ithc4gu1uvb2wZ-slow.log -g select

在这里插入图片描述

1.4 优化SQL查询方法论

查询性能低下最基本的原因是访问的数据太多。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化。对于低效的查询,一般通过下面两个步骤来分析总是很有效:

1.确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候也可能是访问了太多的列。

2.确认MySQL服务器层是否在分析大量超过需要的数据行。

1.4.1 业务层–请求了不需要的数据?

有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序丢弃。这会给MySQL服务器带来额外的负担,并增加网络开销,另外也会消耗应用服务器的CPU和内存资源。比如:

查询不需要的记录

例如先使用SELECT语句查询大量的结果,然后获取前面的N行后关闭结果集(例如取出100条记录,但是只是在页面上显示前面10条 limit这样的 或者count1)。

总是取出全部列

每次看到SELECT*的时候都需要用怀疑的眼光审视,是不是真的需要返回全部的列?很可能不是必需的。取出全部列,会让优化器无法完成索引覆盖扫描这类优化,还会为服务器带来额外的I/O、内存和CPU的消耗。因此,一些DBA是严格禁止SELECT *的写法的,这样做有时候还能避免某些列被修改带来的问题。

什么时候应该允许查询返回超过需要的数据?如果这种有点浪费数据库资源的方式可以简化开发,因为能提高相同代码片段的复用性,如果清楚这样做的性能影响,那么这种做法也是值得考虑的。

或者如果应用程序使用了某种缓存机制,或者有其他考虑,获取超过需要的数据也可能有其好处,但不要忘记这样做的代价是什么。获取并缓存所有的列的查询,相比多个独立的只获取部分列的查询可能就更有好处。

重复查询相同的数据

不断地重复执行相同的查询,然后每次都返回完全相同的数据。比较好的方案是,当初次查询的时候将这个数据缓存起来,需要的时候从缓存中取出,这样性能显然会更好。

1.4.2 执行层–是否在扫描额外的记录

在确定查询只返回需要的数据以后,接下来应该看看查询为了返回结果是否扫描了过多的数据。比如limit 10000,10 其实这个是查询了10010条数据。

对于MySQL,最简单的衡量查询开销的三个指标如下:

这三个指标都会记录到MySQL的慢日志中,所以检查慢日志记录是找出扫描行数过多的查询的好办法。

响应时间

响应时间是两个部分之和:服务时间和排队时间。

服务时间是指数据库处理这个查询真正花了多长时间。

排队时间是指服务器因为等待某些资源而没有真正执行查询的时间—-可能是等I/O操作完成,也可能是等待行锁,等等。

当你看到一个查询的响应时间的时候,首先需要问问自己,这个响应时间是否是一个合理的值。从我们前面章节的讲述中,我们知道如何分析一个SQL查询需要哪些索引以及它的执行计划是什么,然后计算大概需要读取多少个页面和记录数,是能够大致分析出当前响应时间是不是一个合理的值。

扫描的行数和返回的行数

分析查询时,查看该查询扫描的行数是非常有帮助的。这在一定程度上能够说明该查询找到需要的数据的效率高不高。

理想情况下扫描的行数和返回的行数应该是相同的。但实际情况中这种“美事”并不多。

例如不正确的使用Limit,在系统中需要进行分页操作的时候,我们通常会使用LIMIT加上偏移量的办法实现,同时加上合适的ORDER BY子句。

在偏移量非常大的时候,SQL语句就变成了类似select * from order_exp limit 10000,10;

这样的查询,这时MySQL需要查询10010条记录然后只返回最后10条,前面10 000条记录都将被抛弃,这样的代价非常高。这个在前面讲过使用主键id的优化,这里不再赘述(where id >10000 limit 10

又或者在做一个关联查询时,服务器必须要扫描多行才能生成结果集中的一行。扫描的行数对返回的行数的比率通常很小,一般在1:1和10:1之间,不过有时候这个值也可能非常非常大。

扫描的行数和访问的类型

在评估查询开销的时候,需要考虑一下从表中找到某一行数据的成本。MySQL有好几种访问方式可以查找并返回一行结果。有些访问方式可能需要扫描很多行才能返回一行结果,也有些访问方式可能无须扫描就能返回结果。

在EXPLAIN语句中的type列反应了访问类型。访问类型有很多种,从全表扫描到索引扫描、范围扫描、唯一索引查询、常数引用等,速度是从慢到快,扫描的行数也是从小到大。对其中相关的扫描表、扫描索引、范围访问和单值访问的概念要非常熟悉。

如果查询没有办法找到合适的访问类型,那么解决的最好办法通常就是增加一个合适的索引,为什么索引对于查询优化如此重要了。索引让 MySQL以最高效、扫描行数最少的方式找到需要的记录。

对于我们在SQL语句中常见的WHERE条件,一般 MySQL能够使用如下三种方式应用WHERE条件,从效率和扫描行数多少来评价的话,从好到坏依次为:

1、在索引中使用WHERE条件来过滤不匹配的记录。这是在存储引擎层完成的。

2、使用索引覆盖扫描(在Extra列中出现了Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果。这是在 MySQL服务器层(server)完成的,但无须再回表查询记录。

3、从数据表中返回数据,然后过滤不满足条件的记录(在Extra列中出现Using Where)。这在 MySQL服务器层完成,MySQL需要先从数据表读出记录然后过滤。

好的索引可以让查询使用合适的访问类型,尽可能地只扫描需要的数据行。

如果发现查询需要扫描大量的数据但只返回少数的行,那么通常可以尝试下面的技巧去优化它:

1、使用索引覆盖扫描,把所有需要用的列都放到索引中,这样存储引擎无须回表获取对应行就可以返回结果了(在前面的章节中我们已经讨论过了)。

2、改变库表结构。例如使用单独的汇总表。

3、重写这个复杂的查询,让 MySQL优化器能够以更优化的方式执行这个查询。

sysytem innodb达不到 myisam才有的 innodb最多到const

在这里插入图片描述

1.5 重构SQL查询的方法论

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

1.5.2 切分查询

1.5.3 分解关联查询

1.6 从MySQL执行全流程考虑性能优化

1.6.1 为什么查询速度会慢

1.6.2 查询执行的流程再回顾

1.6.3 MySQL客户端/服务端通信

1.6.4 生命周期中的查询优化处理

1.6.5 查询执行引擎

1.6.6 返回结果给客户端

1.6.7 查询状态

1.6.8 通过show profile分析SQL

show processlist

通过show profile分析

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

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

相关文章

File和IO流

1、File 1.1、何为File? File类的对象代表操作系统的文件(文件、文件夹) File类提供了诸如:创建文件对象代表文件,获取文件信息(大小、修改时间)、删除文件、创建文件(文件夹&…

chatgpt赋能Python-pandas归一化python

Pandas归一化Python教程 越来越多的数据分析和机器学习应用需要将数据归一化,以保证数据的统一性和可比性。Pandas是Python中最常用的数据处理库之一,它提供了许多常用的方法,包括数据归一化。本教程将介绍如何使用Pandas进行数据归一化&…

Springboot地方废物回收机构管理的设计与实现

背景 地方废物回收机构的需求和管理上的不断提升,地方废物回收机构管理的潜力将无限扩大,地方废物回收机构管理系统在业界被广泛关注,本系统及对此进行总体分析,将地方废物回收机构信息管理的发展提供参考。地方废物回收机构管理…

回归预测 | MATLAB实现基于贝叶斯线性回归(Bayesian Regression)的多变量输入回归预测

回归预测 | MATLAB实现基于贝叶斯线性回归(Bayesian Regression)的多变量输入回归预测 目录 回归预测 | MATLAB实现基于贝叶斯线性回归(Bayesian Regression)的多变量输入回归预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 Matlab实现基于贝叶斯线性回归(Bay…

为什么要放弃 $ 语法糖提案

《最新,Vue 中的响应性语法糖已废弃》 本文标题中的 $ 语法糖指的就是上文中的响应式语法糖 (Reactivity Transform),那为什么不写 Reactivity Transform 呢?因为这个名实在是太长了… 大家觉得被废弃是因为分不清是正常变量还是响应式变量…

chatgpt赋能Python-pycharm关联anaconda

使用PyCharm关联Anaconda打造高效Python开发环境 PyCharm是一个流行的Python集成开发环境(IDE),而Anaconda则是一个免费、开源的Python发行版。PyCharm与Anaconda的结合使得开发者能够在一个统一的环境中开发Python应用程序。本文将探讨如何…

Vivado综合属性系列之五 USE_DSP

目录 一、前言 二、USE_DSP 2.1 工程代码 2.2 结果 2.3 参考资料 一、前言 ​对于逻辑运算,加、减、乘、除等可以使用逻辑资源LUT实现,也可以使用专用的运算资源DSP来实现。在一些计算量较大时,使用DSP可以节省许多逻辑资源,…

【V2G】电动汽车接入电网优化调度研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

目录显示变应用程序需要权限的解决方法

在平日使用电脑的过程中,好多人通常会一些状况,其中最常见的就是目录变应用程序了,许多用户都不确定电脑目录变应用程序打不开怎么办,这种状况不要焦急,下面小编就来给大伙讲一讲电脑目录骤然目录的方法,一…

Windows上配置访问共享

Windows上配置访问共享 方法一:FTP共享方法二:文件共享 方法一:FTP共享 参考该链接:https://blog.csdn.net/qq_41101213/article/details/94214121 方法二:文件共享 本案例是在windows防火墙开启的状态下配置的 给本…

Redis主从

搭建主从架构 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 5之前叫slave,之后叫replica好像 共包含三个节点,一个主节点,两个从节点。 这里我们会…

chatgpt赋能Python-pandas归一化

深入了解Pandas归一化:什么是归一化,为什么需要归一化? Pandas是Python中最常用的数据分析库之一。Pandas提供了许多功能,使数据分析变得更加轻松。其中,归一化是数据分析中一个重要的概念,它将数据缩放到…

chatgpt赋能Python-pycharm如何横向输出

PyCharm如何横向输出 如果你是Python开发者,那么你一定会使用到PyCharm这个IDE,而且PyCharm的强大也是得到大家的一致认可的。但是,有没有遇到过需要横向输出的情况呢?比如输出一个很长的字符串,但是你希望它能够在你…

【利用AI刷面试题】AI:十道不常见的TypeScript面试题

文章目录 前言😏以下是关于 TypeScript 的一些偏僻的面试题😝1. 泛型约束中的 "extends" 关键字有哪些用法和含义?2. 什么是交叉类型(Intersection Types)?如何在 TypeScript 中定义和使用它们&a…

chatgpt赋能Python-pycharm如何加库

Pycharm如何加库:A Complete Guide Pycharm是一款强大的Python集成开发环境(IDE),它提供了许多有用的工具和功能来简化Python开发过程。尽管Pycharm已经内置了许多功能和工具,但我们在开发过程中仍然需要使用第三方库来提高效率。在本文中&a…

MySQL 常用/见函数

目录 日期函数 字符串函数 数学函数 其它函数 日期函数 获得时分秒: select current_time(); ---------------- | current_time() | ---------------- | 13 :51:21 | ---------------- 日期就是date 获得时间戳: select current_timestamp()…

chatgpt赋能Python-pycharm中添加库

PyCharm中添加库:让你的Python开发更加高效 Python是一种高级编程语言,因其易学易用的特性被广泛应用于Web开发、数据分析、人工智能等领域。PyCharm是Python开发的一种强大的IDE(集成开发环境),它提供了各种有用的功…

【P24】JMeter 正则表达式用户参数(RegEx User Parameters)

文章目录 一、准备工作二、测试计划设计 一、准备工作 慕慕生鲜: http://111.231.103.117/#/login 进入网页后,登录,页面提供了账户和密码 搜索框输入“虾” 右键检查或按F12,打开调试工具,点击搜索 二、测试计划设…

Hantek 5000系列示波器原理图研究

Hantek 5000系列是Hantek(汉泰)2010年左右推出的入门型号示波器,最高采样率1GSa/s,带宽200M。2010年的时候,EEVblog论坛的大佬tinhead给出了该系列示波器的详细原理图(下载),图的可读…

RapidVideOCR(视频硬字幕提取工具)新增exe版

引言 考虑到提取视频字幕的小伙伴大多不是程序员行当,为了降低使用门槛,特此推出界面版的RapidVideOCR Desktop. RapidVideOCR Desktop需要搭配VideoSubFinder使用。它们两个关系如下图所示: #mermaid-svg-md1FaKkTWKdZahtd {font-family:&q…