《高性能MySQL》读书笔记

(参考AOF)


性能优化简介


性能:性能即相应时间,这是一个非常重要的原则。我们通过任务和时间而不是资源来测量性能。

数据库服务器的目的是执行SQL语句,所以它关注的是查询或者语句(查询 == 发送给服务器的指令)。

优化:我们假设优化是服务器在一定的工作负载下尽可能的而减少响应时间。

这里就引申出第二个原则:无法测量就无法有效的优化,所以第一步应该测量时间花在什么地方。

有两种情况会导致不合适的测量:

在错误的时间启动和停止测量

测量的是聚合后的信息,而不是目标活动本身

完成一项任务所需要的时间可以分成两部分:执行时间和等待时间。如果需要优化任务的执行时间,最好的办法就是通过测量定位不同的子任务花费的时间,然后优化去掉一些子任务,降低子任务的执行频率,或者提升子任务的效率。而优化任务的等待时间则相对要复杂一些。

那么如何确认哪些子任务是优化的目标呢?这个时候性能剖析就可以派上用场了。


通过性能剖析进行优化

性能剖析一般有两个步骤:测量任务所花费的时间;然后对结果进行排序,将重要的任务排到前面。

我们将实际的讨论两种类型的性能剖析:基于执行时间的分析和基于等待的分析。

基于时间的分析研究的是什么任务的执行时间最长,而基于等待的分析则是判断任务在什么地方被阻塞的时间最长。

(突然感觉有点郁闷,这一章一直看不通,外面都在说用explain,但是我总觉得还有更核心的问题。会是慢查询日志吗?)

后面会讲一个性能测试工具:pt-qurey-digest,前面就先看着吧。


理解性能剖析

1、值的优化的查询

性能剖析不会自动给出哪些查询值得时间去优化。

对一个占总响应时间不超过5%的查询进行优化,无论如何努力,收益也不会超过5%。第二,如果花费了1000美元去优化一个任务,但业务的收入没有增加,那么可以说反而导致了业务的逆优化。如果优化的成本大于收益,就应该停止优化。

2、异常优化

某些任务即使没有出现再性能剖析输出的前面,也需要优化,比如某些任务执行的次数很少,但是每次执行都非常慢,严重影响用户体验。因为其执行频率低,所以总的响应时间占比并不突出。

3、未知的未知

要知道,工具始终是有局限性的。


剖析MySQL查询


在MySQL当前版本中,慢查询日志是开销最低、精度最高的测量查询时间的工具。慢查询日志带来的I/O开销可以忽略不计,更需要担心的是日志可能消耗大量的磁盘空间。如果长期开启慢查询日志,要注意部署日志轮转工具。或者不要长期开启慢查询日志,只在需要收集负载样本的期间开启即可。

慢查询日志

MySQL 慢查询日志是排查问题 SQL 语句,以及检查当前 MySQL 性能的一个重要功能。

  • 查看是否开启慢查询功能:

mysql> show variables like ‘slow_query%’;

±--------------------±----------------------------------+

| Variable_name | Value |

±--------------------±----------------------------------+

| slow_query_log | OFF |

| slow_query_log_file | /var/lib/mysql/localhost-slow.log |

±--------------------±----------------------------------+

mysql> show variables like ‘long_query_time’;

±----------------±----------+

| Variable_name | Value |

±----------------±----------+

| long_query_time | 10.000000 |

±----------------±----------+

slow_query_log 慢查询开启状态

slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)

long_query_time 查询超过多少秒才记录


默认没有开启慢查询日志记录,通过命令临时开启:

set global slow_query_log=‘ON’;

set global slow_query_log_file=‘/var/lib/mysql/instance-1-slow.log’;

set global long_query_time=2;

永久配置:(自取,我就不永久了)

修改配置文件达到永久配置状态:

/etc/mysql/conf.d/mysql.cnf

[mysqld]

slow_query_log = ON

slow_query_log_file = /var/lib/mysql/instance-1-slow.log

long_query_time = 2

配置好后,重新启动 MySQL 即可。

测试

通过运行下面的命令,达到问题 SQL 语句的执行:

mysql> select sleep(2);

±---------+

| sleep(2) |

±---------+

| 0 |

±---------+

1 row in set (2.00 sec)

然后查看慢查询日志内容:

$ cat /var/lib/mysql/instance-1-slow.log


不要直接打开整个慢查询日志进行分析,这样只会浪费时间和金钱。

建议使用pt-query-digest生成一个剖析报告,如果必要,可以再查看日志中需要关注的部分。


pt-query-digest

pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog、General log、slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump抓取的MySQL协议数据来进行分析。可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进行分组统计,统计出各查询的执行时间、次数、占比等,可以借助分析结果找出问题进行优化。

下载:

wget https://www.percona.com/downloads/percona-toolkit/3.2.1/binary/redhat/7/x86_64/percona-toolkit-3.2.1-1.el7.x86_64.rpm

ls | grep percona-toolkit-3.2.1-1.el7.x86_64.rpm

PT 工具是使用 Perl 语言编写和执行的,所以需要系统中有 Perl 环境。安装相关的依赖包,

[root@xxx ~]# yum install perl-DBI.x86_64

[root@xxx ~]# yum install perl-DBD-MySQL.x86_64

[root@xxx ~]# yum install perl-IO-Socket-SSL.noarch

[root@xxx ~]# yum install perl-Digest-MD5.x86_64

[root@xxx ~]# yum install perl-TermReadKey.x86_64

安装 Percona Toolkit:

rpm -iv percona-toolkit-3.2.1-1.el7.x86_64.rpm

rpm -qa | grep percona

工具目录安装路径:/usr/bin

下载的跟乌龟一样慢,我就先拿些现成的来了。加速包又一直解析不出来。。


解析慢查询日志:

pt-query-digest /var/lib/mysql/VM_0_9_centos-slow.log > slow_report.log

输出结果分为3部分:

汇总信息

[root@VM_0_9_centos ~]# more slow_report.log

230ms user time, 20ms system time, 26.35M rss, 220.76M vsz # CPU和内存使用信息

Current date: Wed Aug 26 15:44:46 2020 # 当前时间

Hostname: VM_0_9_centos # 主机名

Files: /var/lib/mysql/VM_0_9_centos-slow.log # 输入的慢日志路径

整个分析结果的汇总信息

Overall: 258 total, 37 unique, 0.02 QPS, 0.00x concurrency _____________

Time range: 2020-08-26T11:20:16 to 2020-08-26T15:44:11

Attribute total min max avg 95% stddev median

============ ======= ======= ======= ======= ======= ======= =======

Exec time 7s 249us 5s 26ms 4ms 311ms 657us

Lock time 349ms 0 152ms 1ms 348us 12ms 194us

Rows sent 33.01k 0 9.77k 131.03 755.64 742.92 0.99

Rows examine 93.32k 0 9.77k 370.38 874.75 775.00 54.21

Query size 51.71k 15 7.23k 205.23 223.14 615.30 143.84

Overall:总共有多少个查询,该例总共有2.58k(2580)个查询。

Time range:查询执行的时间范围。注意,MySQL5.7版本中的时间格式不同于之 前的版本。

Unique:唯一查询数量,即对查询条件进行参数化以后,总共有多少个不同的查 询。该例为10个。

Attribute:如上述代码段所示,表示Attribute列描述的Exec time、Lock time等属性 名称。

total:表示Attribute列描述的Exec time、Lock time等属性的统计数值。

min:表示Attribute列描述的Exec time、Lock time等属性的最小值。

max:表示Attribute列描述的Exec time、Lock time等属性的最大值。

avg:表示Attribute列描述的Exec time、Lock time等属性的平均值。

95%:表示Attribute列描述的Exec time、Lock time等属性的所有值从小到大排 列,然后取位于95%位置的那个数值(需要重点关注这个值)。

stddev:标准偏差,用于数值的分布统计。

median:表示Attribute列描述的Exec time、Lock time等属性的中位数,即把所有 值从小到大排列,取位于中间的那个数值


第二部分:

对查询进行参数化并分组,然后对各类查询的执行情况进行分析,结果按总执行时间从大到小排列

Profile

Rank Query ID Response time Calls R/Call V/M It

==== =============================== ============= ===== ====== ===== ==

1 0x59A74D08D407B5EDF9A57DD5A4… 5.0003 73.7% 1 5.0003 0.00 SELECT

2 0x64EF0EA126730002088884A136… 0.9650 14.2% 2 0.4825 0.01

3 0x5E1B3DE19F673369DCF52FE6A5… 0.3174 4.7% 2 0.1587 0.00 INSERT data_million_a

4 0x3992A499999D8F9E3ACC220E0F… 0.1334 2.0% 1 0.1334 0.00 ALTER TABLE dtb_table_size dtb_table_size

5 0x66CAA645BA3ED5433EADC39CCA… 0.0991 1.5% 2 0.0495 0.08 SELECT data_million_a

MISC 0xMISC 0.2735 4.0% 250 0.0011 0.0 <32 ITEMS>

Rank:为查询生成的数字编号,表示该分类语句在整个分析结果集中的排名。

Query ID:为查询生成的随机字符串ID(根据指纹语句生成的checksum随机字符串)。

Response time:该查询的总的响应时间和占所有查询的总的响应时间的百分比。

Calls:该查询的执行次数,即本次分析总共有多少条这种类型的查询语句。

R/Call:该查询平均每次执行的响应时间。

V/M:响应时间的方差与均值的比值。

Item:具体的查询语句对象(标准化格式转换的语句形式:去掉了具体的select字段和表名、where条件等)


第三部分:

按照语句执行的总时间,从大到小依次打印每条语句的相关统计信息

Query 1: 0 QPS, 0x concurrency, ID 0x59A74D08D407B5EDF9A57DD5A41825CA at byte 0

Scores: V/M = 0.00

Time range: all events occurred at 2020-08-26T11:20:16

Attribute pct total min max avg 95% stddev median

============ === ======= ======= ======= ======= ======= ======= =======

Count 0 1

Exec time 73 5s 5s 5s 5s 5s 0 5s

Lock time 0 0 0 0 0 0 0 0

Rows sent 0 1 1 1 1 1 0 1

Rows examine 0 0 0 0 0 0 0 0

Query size 0 15 15 15 15 15 0 15

String:

Hosts localhost

Users root

Query_time distribution

1us

10us

100us

1ms

10ms

100ms

1s

10s+

EXPLAIN /!50100 PARTITIONS/

select sleep(5)\G

Time range:查询执行的时间范围。注意,MySQL5.7版本中的时间格式不同于之 前的版本。

Attribute:如上述代码段所示,表示Attribute列描述的Count、Exec time、Lock time等属性名称。

pct:表示该分组语句(这里指上述代码段中“Query 1”代表的分组语句,具体的语 句样本在EXPLAIN …关键字下面有输出。另外,在上述代码段中,如total、min等计算值

都是针对该语句分组的,下文中不再赘述)的total值(该分组语句的统计值)与统计样本 中总的所有语句统计值的占比。

total:表示Attribute列描述的Count、Exec time、Lock time等属性的统计值。

min:表示Attribute列描述的Exec time、Lock time等属性的最小值。

max:表示Attribute列描述的Exec time、Lock time等属性的最大值。

avg:表示Attribute列描述的Exec time、Lock time等属性的平均值。

95%:表示语句对应的Exec time、Lock time等属性值从大到小排序之后,位于 95%位置的那个数值(需要重点关注这个值)。

stddev:标准偏差,用于数值的分布统计。

median:代表对应属性值的中位数,将所有值从小到大排列,取位于中间的那个 数值。

Databases:库名。

Users:各个用户执行的次数(占比)。

Query_time distribution:查询时间分布,由“#”字符表示的长短体现了语句执行时 间的占比区间。从上述代码段中可以看到,执行时间在1s左右的查询数量占绝大多数。

Tables:使用查询语句中涉及的表生成的用于查询表统计信息和表结构的SQL语 句文本。

EXPLAIN:表示查询语句的样本(方便复制出来查看执行计划。注意,该语句不 是随机生成的,而是分组语句中最差的查询SQL语句)


优秀资料


参考资料来源:Mysql性能瓶颈深度定位分析

我们在性能测试过程中,经常会遇到Mysql出现性能瓶颈的情况,对于数据库来说,所谓的性能瓶颈无非是慢SQL、CPU高、IO高、内存高,其中前三个举实际例子来进行性能分析,最后内存高只是方法性说明(实际测试项目中没遇到过):

首先我们要保证没有数据库配置方面的性能问题,毕竟在性能测试前,对一些基本配置要撸一遍,避免犯低级错误。

慢SQL定位分析

首先业务系统慢,肯定是体现在响应时间上,所以在性能测试中,如果发现慢我们就从响应时间上进行拆分,最后拆到mysql,那就是分析慢SQL,同样如果在高并发时发现mysql进程占CPU很高,也是优先分析是否存在慢SQL,而且判断慢SQL还是比较简单的,对于Mysql就是看慢日志查询。

获取到慢SQL,当然是要实际验证一下有多慢,是否索引配置了,拿一条实际测试项目的SQL语句来分析:

explain SELECT count(c.id)

FROM administrative_check_content c

LEFT JOIN administrative_check_report_enforcers e ON c.report_id=e.report_id

LEFT JOIN administrative_check_report r ON c.report_id = r.id

WHERE e.enforcer_id= ‘ec66d95c8c6d437b9e3a460f93f1a592’;

可以分析出这条语句,86%的时间是花在了Sending data(所谓的“Sending data”并不是单纯的发送数据,而是包括“收集 [检索] + 发送数据”):

在这里插入图片描述


用show profile进行sql分析:

开启分析也很简单,使用临时开启执行set profiling=1即可(这个功能会缓存最近查询的分析语句,默认15条,最多100条,适合在压测结束后开展sql分析,用完后再设成0关闭),如下:

#显示是否开启Profiling,以及最多存储多少条

show variables like ‘%profil%’;

#开启Profiling

set profiling=1;

#执行你的SQL

#在这里我们主要是执行前面所找到的慢SQL

#查看分析

show profiles;

通过show profiles我们可以看到我们上面执行的那条SQL(Query_ID=18,为了确保监视最新的数据,Query_ID最好取25)

在这里插入图片描述

执行:show profile cpu,memory,block io for query 18;

在这里插入图片描述

可以看出也是Sending data总共消耗0.39秒,其中CPU_user时间占比较高(简单的一条SQL语句消耗这些时间就算很高了),另外还能看到这条SQL的IO开销(因为查询,都是ops out块输出)

也可以通过SQL查表来查看以上记录:

总结

蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。


经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

蚂蚁金服5面,总结了49个面试题,遇到的面试官都是P7级别以上

olor_FFFFFF,t_70)

执行:show profile cpu,memory,block io for query 18;

在这里插入图片描述

可以看出也是Sending data总共消耗0.39秒,其中CPU_user时间占比较高(简单的一条SQL语句消耗这些时间就算很高了),另外还能看到这条SQL的IO开销(因为查询,都是ops out块输出)

也可以通过SQL查表来查看以上记录:

总结

蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。


经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

[外链图片转存中…(img-ke5gKFwf-1714489978079)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
高性能MySQL》是由Baron Schwartz、Peter Zaitsev和Vadim Tkachenko等人合著的一本MySQL性能优化的经典著作。这本书深入浅出地介绍了MySQL数据库的内部原理、优化技巧以及高性能应用的方法。 《高性能MySQL》的内容主要分为四个部分:MySQL基础、查询性能优化、服务器性能优化和高可用性。在MySQL基础部分,书中详细介绍了MySQL的体系结构、存储引擎、索引等基础知识,通过深入理解这些基础知识,读者能更好地理解后续的优化技巧。在查询性能优化部分,书中介绍了如何编写高效的查询语句、优化查询执行计划以及利用索引提高查询性能的方法。在服务器性能优化部分,作者介绍了如何调整MySQL的配置参数、优化内存使用、并发访问等方面,以提高整个数据库服务器的性能。在高可用性部分,书中介绍了如何使用主从复制、MySQL集群等技术实现数据库的高可用性,以及如何进行备份和恢复等。 除了详细介绍MySQL的内部原理和性能优化技巧外,这本书还给出了大量的实例和案例,帮助读者更好地理解和应用所学知识。此外,书中还涉及到了一些开源工具和测试技术,如pt-query-digest、Percona Toolkit等,帮助读者更好地进行性能分析和问题诊断。 总之,《高性能MySQL》是一本非常实用的MySQL性能优化指南,适合那些对MySQL性能优化有一定基础的读者。无论是DBA还是开发人员,都可以从这本书中学到很多有关MySQL性能优化的实用知识,帮助他们更好地管理和优化MySQL数据库,提升系统的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值