剖析Mysql查询性能和诊断间歇性问题

剖析Mysql查询性能

说明

本章主要通过,如何确认服务器是否达到了性能最佳的状态,找出某条语句为什么执行不够快,以及诊断被用户描述成“停顿”、“堆积”、或者“卡死”的某些间歇性疑难故障。这三个问题做出解答。我们这里将性能定义为完成某件任务所需要的时间度量,换句话说,性能即响应时间。我们通过任务和时间而不是资源来测量性能。数据库服务器的目的是执行SQL语句,所以它关注的任务是查询或者语句,如SELECT、UPDATE、DELETEDE等。数据库服务器的性能用查询的相应时间来度量,单位是每个查询花费的时间。

优化

第一步:测量时间花在什么地方(无法测量就无法优化),我们应该先要去搞清楚为什么服务器执行查询需要这么长时间,时间都花在了哪里,好去针对进行优化。我们不应该都将精力放在修改一些东西上,却很少去进行精确的测量。如果我们通过测量了系统中完整并且正确的数据,性能问题一般都能暴露出来。

通过性能剖析进行优化

一旦掌握并实践面向相应时间的优化方法,就会发现需要不断地对系统进行性能剖析。性能剖析是测量和分析时间花费在哪里的主要方法。一般分为两个步骤:测量任务花费的时间,然后对结果进行统计和排序,将重要的任务排到前面。
我们将实际讨论两种类型的性能剖析:基于执行时间的分析和基于等待的分析。基于执行时间的分析研究的是什么任务的执行时间最长,而基于等待的分析则判断任务在什么地方被阻塞的时间最长。如果任务执行时间长是因为消耗了太多的资源且大部分时间花费在执行上,等待的时间不多,这种情况下基于等待的分析作用就不大。反之亦然,如果任务一直在等待,没有消耗什么资源,去分析执行时间就不会有什么结果。如果不能确定问题是出在执行还是等待上,那么两种方式都需要试试。

理解性能剖析

值得优化的查询

一些只占总相应时间比重很小的查询是不值得优化的。根据阿姆达尔定律,对一个占总响应时间不超过5%的查询进行优化,无论如何努力,收益也不会超过5%。第二如果花费了1000美元去优化一个任务,但业务收入没有任何增加,那么可以说反而导致业务被逆优化了1000美元。如果优化的成本大于收益,就应当停止优化。

异常情况

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

未知的未知

一款好的性能剖析工具会显示可能的“丢失的时间”。丢失的时间指的是任务的总时间和实际测量到的时间之间的差。例如,如果处理器的cpu时间是10秒,而剖析到的任务总时间是9.7秒,那么就有300毫秒的丢失时间。这可能是有些任务没有测量到,也可能是由于测量的误差和精确度问题的缘故。如果工具发现了这类问题,则要引起重视,因为有可能错过了某些重要的事情。即使性能剖析没有返现丢失时间,也需要注意考虑这类问题存在的可能性,这样才不会错过重要的信息。

被掩藏的细节

性能剖析无法显示所有响应时间的分布。只相信平均值是非常危险的,它会隐藏很多信息,无法表达全部情况。

剖析服务器负载

剖析服务器负载能帮助我们解决某些特定的难题。还可以降低服务器的整体压力,这样所有的查询都将因减少了对共享资源的争用而受益。

捕获MySQL的查询到日志文件

我们需要通过设置long_query_time 为0 来设置捕获所有的查询,而且查询的相应时间单位已经可以做到为妙级。

分析日志文件

通过pt-query-digest分析MySQL查询日志。它可以分析binlog、General log、slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump抓取的MySQL协议数据来进行分析。可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进行分组统计,统计出各查询的执行时间、次数、占比等,可以借助分析结果找出问题进行优化。
参考博客 https://blog.csdn.net/wxc20062006/article/details/52387505

剖析单条查询

在定位到需要优化的单条查询后,可以针对此查询,获取更多信息。找出为什么会消耗这么长时间执行,以及需要如何去优化。
1.使用SHOW PROFILE

https://blog.csdn.net/fantexi1984/article/details/74088879

2.使用SHOW STATUS
这个命令返回了一些计数器。

诊断间歇性问题

比如系统偶尔停顿或者慢查询,很难诊断。有些幻影问题只在没有注意到的时候才发生,而且无法确认如何重现。

单条查询问题还是服务器问题

使用SHOW GLOBAL STATUS
这个方法实际上就是通过较高的频率比如一秒执行一次SHOW GLOBAL STATUS命令捕获数据,问题出现时,则可以通过某些计数器()比如Threads_running、Threads_connected、Questions和queries)的“尖刺”,或者“凹陷”来发现。这个方法比较简单,所有人都可以使用,不要特殊的权限,对服务器的影响也很小,所以是一个花费时间不多却能很好地了解问题的好方法。这个命令每秒输出一行数据,可以运行几个小时或者几天,然后将结果绘制成图形,这样就可以方便地发现是否有趋势的突变。如果问题确实是间歇性的,发生的频率又较低,也可以根据需要尽可能长时间地运行此命令,直到发现问题在回头来看输出结果。大多数情况,通过输出结果都可以更明确地定位问题。

使用SHOW PROCESSLIST
这个方法是通过不停地捕获SHOW PROCESSLIST 的输出,来观察是否有大量线程处于不正常的状态或者有其他不正常的特征。例如查询很少会长时间处于statistics状态,这个状态一般是指服务器在查询优化阶段如何确定表关联的顺序—通常是非常快的。

使用查询日志
去查找吞吐量突然下降的原因

理解并发的问题
可视化数据最具有说服力。可以选用gnuplot或者R。或者其他绘图工具将结果绘制成图形。

捕获诊断数据

当出现间歇性问题时,需要尽可能多地收集所有数据,而不是问题出现时的数据。这里需要搞清楚两件事:
1.一个可靠且实时的触发器,也就是能区分什么时候问题出现的方法。
2.一个收集诊断数据的工具
诊断触发器
这个是问题出现时能够捕获问题数据的基础。有两个常见的问题可能导致无法达到预期的结果:误报或者漏检。误报是指收集了很多诊断数据,但其间其实没有发生问题,这可能浪费时间,而且令人沮丧。而检漏则指在问题出现时没有捕获到数据,错失了机会,一样会浪费时间。所以在开始收集数据前多花一点时间来确认触发器能够真正地识别问题是划算的。

需要收集什么样的数据
尽可能收集所有能收集的数据,但只在需要的时间段内进行收集。包括系统的状态、CPU利用率、磁盘使用率和可用空间、ps的输出采样、内存利用率、以及可以从mysql获得的信息,如SHOW STATUS 、SHOW PROCESSLIST和SHOW INNODB STATUS等。

解释结果
通过设置好的触发条件获得的数据进行分析。一检查问题是否真的发生了,二是否有非常明显的跳跃性变化。

《mysql高性能》给出了诊断案例

猜你喜欢

转载自blog.csdn.net/qq_18377515/article/details/80863784