3、服务器性能剖析

性能优化简介

**我们将性能定义为完成某件任务所需要的时间度量,换句话说,性能即响应时间,这是一个非常重要的原则。**我们通过任务和时间而不是资源来测量性能。数据库服务器的目的是执行sql语句,所以他关注的任务是查询或者语句,如SELECT、UPDATE、DELETE等。数据库服务器的性能用查询的响应时间来度量。单位是每个查询花费的时间。
假如你认为性能优化是降低CPU利用率,那么可以减少对资源的使用。但是资源是用来消耗并用来工作的,所以有时候消耗更多的资源能够加快查询速度。很多时候将使用老版本InnoDB引擎的Mysql升级到新版本后,CPU利用率会上升很厉害,这并不代表性能出现了问题,反而说明新版本对资源的利用率上升了。
如果把性能优化仅仅看成是提升每秒查询量,这其实只是吞吐量优化,吞吐量的提升可以看作性能优化的副产品。对查询的优化可以让服务器每秒执行更多的查询,因为每秒查询执行的时间更短了。
如果优化的目标是降低响应时间,那么就需要理解为什么服务器执行查询需要这么多时间,然后去减少或者消除那些对获得查询结果来说不必要的工作。也就是说,先要搞清楚时间花在哪。这就引申出优化的第二个原则:无法测量就无法有效地进行优化。所以第一步应该测量时间花在什么地方。

通过性能剖析进行优化

性能剖析是测量和分析时间花费在哪的主要方法。性能剖析一般有两个步骤:

  • 测量任务所花费的时间
  • 对结果进行统计和排序,将重要的任务排在前面

理解性能剖析

Mysql的性能剖析(profile)将最重要的任务展示在最前面,但有时候没显示出现的信息也很重要。

值得优化的查询

性能剖析不会自动给出哪些查询值得花时间去优化。这里需要强调两点:

  1. 一些只占总响应时间比重很小的查询是不值得优化的
  2. 如果优化的成本大于收益,应该停止优化

异常情况

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

未知的未知

一款好的性能剖析工具会显示可能得丢失时间,丢失的时间是指任务的总时间和实际测量的时间之间的差。这可能是有些任务没有测量到,也可能是由于测量的误差和精度问题的缘故。

被掩藏的细节

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

对应用程序进行性能剖析

对任何需要消耗时间的任务都可以做性能剖析,当然也包括应用程序。实际上应用程序一般比剖析数据库服务器容易。虽然性能问题大多数情况下都和数据库有关,但应用导致的性能问题也不少。一般建议对系统进行性能剖析还是自上而下进行。性能瓶颈可能有很多影响因素:

  • 外部资源,比如调用了外部的web服务
  • 应用需要处理大量的数据,比如分析一个超大的xml文件
  • 在循环中执行昂贵的操作,比如滥用正则
  • 使用了低效的算法,比如使用暴力搜索算法来查询列表中的项

剖析Mysql查询

对查询进行性能剖析有两种方式,每种方式都有各自的问题。可以剖析整个数据库服务器,这样可以分析出哪些查询是主要的压力来源。

剖析服务器负载

服务器端的剖析很有价值,因为在服务器端可以有效地审计效率低下的查询。定位和优化慢查询能够显著提升应用性能,也能解决某些特定的难题。还可以降低服务器的整体压力,这样所有的查询都将因为减少了对共享资源的争用而收益。降低服务器的负载也可以推迟或避免升级更昂贵硬件的需求,还可以发现和定位糟糕的用户体验,比如某些极端情况。

捕获Mysql的查询到日志文件中

在Mysql中慢查询日志最初只是捕获比较慢的查询,而性能剖析却需要针对所有的查询。而且在Mysql5.0及以前的版本中,慢查询日志的响应时间的单位是秒,粒度太粗了。在Mysql5.1的更新版本中,慢日志的功能已经被加强了,可以通过设置long_query_time为0来捕获所有的查询,而且查询的响应时间单位已经做到微秒级。
在Mysql的当前版本中,慢查询日志是开销最低,精度最高的测量查询时间的工具。
Mysql的另一种查询日志就是通用日志,但很少用于分析和剖析服务器性能。通用日志在查询请求到服务器时进行记录,所以不包含响应时间和执行计划等重要信息。

分析查询日志

剖析单条查询

在定位到需要优化的单条查询后,可以针对此查询获取更多的信息,确认为什么会花费这么长时间,以及需要如何去优化。下面介绍几种方法1是如何显示查询的执行情况的:

使用SHOW PROFILE

SHOW PROFILE 命令是在Mysql5.1版本后引入的,默认是禁用的,可以通过命令修改

SET profiling = 1;

然后在服务器上执行的所有语句都会测量器耗费的时间和其他一些查询执行状态变更相关的数据。
当一条查询提交给服务器时,此工具会记录剖析信息到一张临时表,并且给查询赋予一个从1开始的整数标识符。在执行完一条查询语句后我们可以使用以下命令来查看剖析报告。剖析报告给出了查询执行的每个步骤及其花费时间。看结果很难直接确定是哪个步骤花费的时间最多因为输出是按照执行顺序而不是花费时间排序。如果不使用SHOW PROFILE 而直接查询 INFORMATION_SCHEMA 中对应的表,则可以根据自己的需要进行指定的查询。

SHOW PROFILE FOR QUERY ID;

使用SHOW STATUS

Mysql的SHOW STATUS 命令返回了一些计数器,既有服务器级别的全局计数器,也有基于某个连接会话级别的计数器。如果执行SHOW GLOBAL STATUS 则可以查看服务器级别的从服务器启动时开始计算的查询次数统计。
SHOW STATUS的大部分结果都只是一个计数器,可以显示某些活动如读锁引的频繁程度,但无法给出消耗了多少时间。

使用慢查询日志

使用Performance Schema

使用性能剖析

当获得服务器或者查询的剖析报告后,怎么使用呢?好的报告能将潜在的问题显示出来,但最终的解决方案还需要用户决定。优化查询时用户需要对服务器如何执行查询有较深的了解,这里的用户当然是指研发啦。

诊断间歇性问题

间歇性的问题比如系统偶尔停顿或者慢查询,很难诊断。有些幻影问题只在没有注意到的时候才发生,而且无法确认如何重现,诊断这样的问题往往要花很多的时间。
尽量不要使用试错的方式来解决问题,因为结果可能会变得更坏。

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

发现问题后首先要确认这是单条查询的问题还是服务器的问题。如果服务器上所有的程序都变慢,有突然都变好,每一条查询也都变慢了,那么慢查询可能就不一定是原因,而是由于其他问题导致的结果。反过来说,如果服务器整体运行没有什么问题,只有某些查询偶尔变慢,就需要将注意力放到这条特定的查询上面。

使用SHOW GLOBAL STATUS

这个方法实际上就是以较高的频率比如一秒一次执行这个命令捕获数据。

使用SHOW PROCESSLIST

这个方法是通过不停的捕获SHOW PROCESSLIST 的输出,来观察是否有大量线程处于不正常的状态或者有其他不正常的特征。

使用查询日志

如果要通过查询日志发现问题,需要开启慢查询日志并在全局级别设置long_query_time为0,并且要确认所有的连接都采用了新的设置。

捕获诊断数据

当出现间歇性问题时,需要尽可能多地收集所有数据,而不只是问题出现时的数据。

诊断触发器

触发器非常重要,这是在问题出现时能够捕获数据的基础。有两个常见的问题可能导致无法达到预期的结果:误报或者漏检。误报是指收集了很多诊断数据,但期间其实没有发生问题。而漏检是指在问题出现时没有捕获到数据。所以在开始收集数据前要确认触发器能够真正的识别问题。

需要收集什么样的数据

在需要的时间段内尽可能收集所有能收集的数据。包括系统状态、CPU利用率、磁盘使用率和可用空间、ps的输出采样,内存利用率以及可以从Mysql获得的信息。

解释结果数据

当我们收集完所需要的数据后,那么我们接下来要怎么做呢?第一,检查问题是否真的发生了,因为有很多误报的情况。第二,是否有非常明显的跳跃性变化。查看异常的查询或事务行为。

你可能感兴趣的:(Mysql高性能学习,mysql,java,后端,面试)