Query Profiling,即查询分析技术,是 MySQL 数据库提供的一种诊断 SQL 性能的方法,同时也被视为分析数据库整体性能的有效技术。


MariaDB性能优化,我终于搞清楚了!_java
图片来自 Pexels

用户可以在开启 Profiling 的情况下,查看当前会话中 SQL 执行时间消耗分布,系统时间,CPU 用户时间,以及过程中涉及到的关键函数在源代码文件中的定位等。


由于单个大中型应用程序可以在单位时间内完成多个查询,因此 Query Profiling 是数据库优化调整的重要组成部分,它既可作为数据库性能优化的积极主动措施,亦可用于诊当前断数据库性能是否存在问题。


在实际工作场景中,如果不采用可靠的查询分析技术,相关技术人员往往很难定位数据库中性能瓶颈及性能不佳问题的根源所在。


作为 MySQL 的一个分支,MariaDB Server 自带的内置工具中为我们提供了 Query Profiling 相关的查询概要分析技术。


我们以 Slow Query Log(慢速查询日志)和 Performance Schema(性能策略模型)这两类 MariaDB Server 内置工具为例,深入探索查询分析技术的价值。


MariaDB vs MySQL


首先让我们来回顾一下 MariaDB 和 MySQL 这两种产品间的亲属关系。


早在 2010 甲骨文宣布收购 Sun 公司的那天,MySQL 之父 Michael“Monty”Widenius就派生了 MySQL,进而推出 MariaDB,从此便吸引了一大批 MySQL 开发人员为之效力。


如今 MariaDB 已经成为了 MySQL 发展最快的一个分支,相较于 MySQL 本身,具有更丰富的功能及更优越的性能。


MariaDB 并非孤立的一个分支,它是基于相应的 MySQL 版本而存在的。例如,MariaDB 5.1.53 是在 MySQL 5.1.53 基础上,修复了之前的 Bug,添加了存储引擎,新功能等,性能方面也做了相应改进。


Slow Query Log(慢速查询日志)


MariaDB 和 MySQL 都有 Slow Query Log(慢速查询日志)这一功能。该日志中记录了一些被认为执行速度非常缓慢且可能存在问题的查询语句。


这里的“慢速”查询定义为运行时间比 [long_query_time] 全局系统变量值(默认为 10 秒)长的查询语句。


值得一提的是在文件记录中允许使用“微秒”,而在表记录中却不行,因而这里的时间单位为“秒”。


通过全局系统变量配置慢查询日志


除了上面提到的 [long_query_time] 全局系统变量外,还有一些其他变量用来确定 Slow Query Log(慢查询日志)的行为状态。


在默认情况下,Slow Query Log 是禁用的,若要启用,则需要将 [slow_query_log] 系统变量值设置为 1。


此外“log_output”服务器系统变量决定了输出是以什么形式被写入的,这个变量值也可以设置为禁用。在默认情况下,日志允许被写入文件,也可以写入表。


[log_output] 服务器系统变量的有效取值为 [TABLE”,“FILE”或“NONE]。


该文件的默认名称为 [host_name-slow.log],也可以使用 [–slow_query_log_file = file_name] 选项进行设置,这里使用的表是 MySQL 系统数据库中的 [slow_log] 表。


建议这些变量最好在“my.cnf”或“mariadb.cnf”配置文件中进行设置,这类文件通常存储在 Linux 的“/ etc / mysql /”目录。


如果是 Windows 系统,那么就存储在 Windows 系统目录(通常为 C:\ Windows\System)中。


配置文件中做如下设置:

  • 启用慢查询日志:slow_query_log = 1

  • 以秒/微秒为单位设置定义慢查询的时间:long_query_time = 5

  • 提供慢速查询日志文件的名称:slow_query_log_file = /var/log/mysql/slow-query.log

  • 需要记录不使用索引的查询语句:log_queries_not_using_indexes


以上设置在服务器重启后生效。


查看 Slow Query Log(慢查询日志)


已写入文件的慢查询日志可以通过任何文本编辑器打开进行查看,下面是一则慢查询日志的示例内容:

MariaDB性能优化,我终于搞清楚了!_java_02

通过文本编辑器来查看慢查询日志看似非常方便,但随着日志内容(数据量)的增长,很可能存在内容丢失的情况。


即显示不完整,这是由于文本编辑器自身无法承载越来越大的日志容量,而造成日志中部分内容解析缺失的风险。


为了避免这类情况的发生,MariaDB 为我们提供了 mysqldumpslow 工具,该工具可以通过汇总信息来简化过程,从而更可靠且有效地展示日志内容。


“mysqldumpslow”的可执行文件与 MariaDB 是捆绑在一起的,所以只需通过命令行将需要显示的日志路径传递给它即可。


从下面的 Demo 中可以获悉,通过“mysqldumpslow”呈现的日志内容可读性更强,并且还支持分组显示。

MariaDB性能优化,我终于搞清楚了!_java_03

“mysqldumpslow”命令可以通过指定不同的参数来定制化输出格式,如下示例中将显示按平均查询时间排序的前 5 个查询:

[ mysqldumpslow -t 5 -s at /var/log/mysql/localhost-slow.log ]


slow_log 一览表


如果你对上述 log 日志中显示的内容不熟悉,可以结合 slow_log 表来帮助理解。


如下是日志中每个字段对应的详情描述:

MariaDB性能优化,我终于搞清楚了!_java_04

下图所示是针对 slow_log 表的 SELECT ALL 示例结果:MariaDB性能优化,我终于搞清楚了!_java_05
还可以通过 slow_log 表来模拟 Linux 的“ tail -100 log-slow.log”命令,列出最新查询记录(最后 100 个查询),如下图所示:MariaDB性能优化,我终于搞清楚了!_java_06

为了方便日后频繁调用,我们也可以专门创建一个存储过程(如SHOW_LATEST_SLOW_QUERIES),需要显示的查询个数可以通过输入参数传递给这个存储过程。


这样一来当我们需要列出指定数量的查询记录时,就不需要每次都重复键入相同的 SELECT 语句了。


测试 Slow Query Log(慢查询日志)


为了更有效地在生产环境中获取我们想要的慢查询日志信息,通常情况下,我们需要做一些设置,例如规定哪些查询必须被写入 Slow Query Log(慢查询日志)。


正如上文中提到,在启用日志记录后,根据 log_output 变量值的设定,运行时间比  [long_query_time]  全局系统变量值长的那些查询将记录在 Slow Query Log(慢查询日志)或 slow_log 表中。


除了指定  [long_query_time]  时间外,我们还可以通过 select 语句根据不同的需求指定相应的可变时间。


这个操作需要结合 sleep() 函数使用,该函数(根据传入的 duration 参数值 N)会暂停当前查询 N 秒,然后返回 0, 如果 sleep() 函数被中断,则返回 1。


如下所示,假设尚未指定  [long_query_time]  全局系统变量的值,那么默认值为 10 秒。


因此,[SELECT SLEEP(11);] 这条 select 语句会被记录到慢日志中:MariaDB性能优化,我终于搞清楚了!_java_07

通过 Performance Schema 进行查询分析


我们可以通过另一种服务器性能工具 Performance Schema 来监视服务器性能。


Performance Schema 是 MariaDB 5.5 中被引入的,以存储引擎的方式实现;因此,在 MariaDB 的存储引擎列表中可以找到 Performance Schema。


图中的“Performance Schema”的功能默认情况下是禁用的,我们可以通过如下设置逐一开启:


①在 my.cnf 或 my.ini 文件的 [mysqld] 部分中添加以下行:

performance_schema = on

需要注意的是,“performance schema”无法在运行时被激活,它必须在服务器启动时通过配置文件进行设置。


Performance Schema 存储引擎包含一个名为 performance_schema 的数据库,该数据库又由许多表组成,可以使用常规 SQL 语句查询这些表以获取各种性能信息。


②消费者数据设置


为了收集数据,我们需要对收集哪些消费者触发的数据进行设置,这些设置可以在服务器启动时或在运行时进行。


通过以下语句在运行时对所需数据进行设置并检测:

UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES';
UPDATE performance_schema.setup_instruments
SET ENABLED = ‘YES’, TIMED = ‘YES’;

通过 WHERE NAME 启用/禁用对应的查询语句,通过将 ENABLED 设置为“ NO”来禁用检测。


以下将启用配置文件中所有阶段的所有检测:MariaDB性能优化,我终于搞清楚了!_java_08
通过更新 setup_instruments 表,确保启用了语句和阶段检测:

UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE '%statement/%';

UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE '%stage/%';

启用 events_statements_ * 和 events_stages_ * 使用者:
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE '%events_statements_%';

UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE '%events_stages_%';

在缩小了感兴趣的范围后,有两种方法可以进行监控:

  • 在摘要视图中查看原始数据,从而全面了解实例的用法。

  • 快照数据,并计算随时间变化的增量,进而了解事件的变化率。


下面我们以查看原始摘要数据为例:


运行要分析的语句:

MariaDB性能优化,我终于搞清楚了!_java_09

通过查询“events_statements_history_long”这张表,来标识语句的 EVENT_ID。此步骤类似于运行 SHOW PROFILES 来标识 Query_ID。


以下查询将产生类似于 SHOW PROFILES 的输出:MariaDB性能优化,我终于搞清楚了!_java_10

查询“events_stages_history_long”这张表,来检索语句的阶段事件。阶段使用事件嵌套链接到语句。


每个阶段事件记录都有一个 NESTING_EVENT_ID 列,其中包含父语句的 EVENT_ID。MariaDB性能优化,我终于搞清楚了!_java_11

Monyog 监控工具


现在我们已经知道 Slow Query Log(慢查询日志)专门用于记录那些运行时间过久且被认为存在问题的查询语句,即运行时间超过 long_query_time 全局系统变量值的查询语句。


而 Performance Schema 是一个存储引擎,可用于在摘要视图中查看原始数据以及随时间推移的过程中涉及到的性能状态。


这两种工具都有其自身的长处。例如,Slow Query Log(慢查询日志)易于使用,且可以通过任何文本编辑器进行查看。


Performance Schema 允许我们使用常规的 SQL 语句对其一系列表进行查询,以获取各类性能信息。


然而,此二者都不可避免会产生大量的数据信息,从而导致冗余且加重各自数据处理的负担。


庆幸的是,Monyog 监控工具可以有效地为我们缓解这个问题,不仅如此,作为专业的监控工具,它还能给我们带来巨大的价值。


Monyog 是一款优秀的 MySQL 监控工具,可以实时监测 MySQL 服务器,查看 MySQL 服务器的运行状态,支持查询分析功能,还可以帮助用户掌握服务器的运行状态,查看在任意时间点绘制的具有详细查询信息的图表。


Monyog 不仅是实时监视工具,还具有 RDS OS 和基于文件的日志监视功能,包括在单个视图中的常规查询,慢速查询和错误日志,还能通过 CloudWatch API 查看 RDS OS 指标,例如 CPU 利用率,RAM 利用率等。


由于在 MariaDB 中,默认情况下禁用慢查询日志。必须将 slow_query_log 全局系统变量设置为 1 来启用它。


此外还有一些其他系统变量的应用设置,如:

  • 以秒/微秒为单位设置定义慢查询的时间

  • 是否写入文件或表

  • 用于提供慢速查询日志文件的名称

  • 记录那些不使用索引的查询


在 Monyog 中的 Slow Query Log(慢查询日志)设置,可以直接通过“Server Settings dialog”对话框的“ADVANCED ”选项卡配置上述所有设置。


步骤如下:

  • 点击服务器图标

  • 点击服务器摘要框上的省略号

  • 弹出“编辑服务器”窗口

  • 点击 ADVANCED

  • 点击 MySQL 查询日志项


MySQL 查询日志项的 ADVANCED 选项卡包含常规查询,慢速查询和错误日志的设置。


该 Server Settings dialog (服务器设置对话框)可以让我们把 Slow Query Log(慢查询日志)的设置应用到当前服务器,或与当前服务器拥有相同标签的其余服务器。


最后单击“Save”按钮关闭对话框,并保存 Slow Query Log(慢查询日志)设置。MariaDB性能优化,我终于搞清楚了!_java_12

Monyog 监控图表


①Dashboard Metrics


DBA 通过 Dashboard 显示的一组图表,就可以轻松了解所有 MySQL 服务器的安全性,可用性以及性能状况。


Monyog 自带默认的 Dashboard“Performance metrics”性能指标,DBA 也可以为一个或多个服务器指定数据库和操作系统指标,创建一组自己的专属图表。


例如查询性能指标中包含“Queries Executed”,“ Statements”和“Query Cache Efficiency”。


Dashboard 上显示的所有图表均可以 PDF/JPG/PNG 格式导出:

MariaDB性能优化,我终于搞清楚了!_java_13

②查看 MySQL 日志详细信息


Monyog Monitors 页面显示服务器参数和指标的详细显示。


单击“ MONITOR GROUP”下的“MySQL Logs”项,将会显示被监控下的服务器对应的“常规查询”,“慢速查询”(红色框标注)和错误日志的详细信息。


Slow Query 慢查询信息包括:

  • 慢日志——是否已启用?(是/否)

  • 最慢查询执行时间,以秒为单位

  • 慢查询的数

  • 是否记录那些不使用索引的查询?(是/否)
  • MariaDB性能优化,我终于搞清楚了!_java_14

③趋势值图


与原始数据相比,利用图表显示大量数据以及数据间不同部分的相关性,更加简洁明了,易于理解,可读性也更强。


趋势值图就是这样一类图表,用于显示一段时间内数据的变化趋势。由于数据的波动,单点测量可能会不准确,产生误差。


因而,随着时间推移来呈现数据的趋势走向,可以使我们更有效地获取实际性能,有针对性地基于已建立的目标监控实际性能状况。


下图是某主服务器趋势图示例:


上图中“SERVERS”图例列出了 SQL 日志中的所有服务器。每个服务器图例都有各自的颜色,以便在图表中能轻松识别。


由于当前图中只显示了主服务器趋势数据,其余对应服务器的趋势值均未出现在图中,所以呈灰色。通过单击服务器图例,可以随意切换需要显示的服务器数据趋势。


④显示特定时间范围内的趋势值


在上面的趋势图中,仅仅显示了时间段内某服务器上所有的趋势数据。


在 Monyog Professional,Enterprise 和 Ultimate 版本中,我们还可以通过 TIMEFRAME 下拉列表中的“History”选项来指定特定时间的范围。


可选择的时间范围包含多个时间间隔,例如“Today”,“Yesterday”和“Last 2 Days” ,也可以自定义范围,设置开始和结束字段;单击任何一个自定义范围字段都会显示日历,用于选择确切的日期时间。
下图所示基于特定时间范围内的各服务器慢查询数量趋势值:

MariaDB性能优化,我终于搞清楚了!_java_15

⑤查询分析器


在“查询分析器”选项卡中,选择所需的 MySQL 服务器以及要分析的日志类型(包括慢查询日志),单击分析按钮开始分析。

几秒钟后,将显示如下分析结果,页面上半部分包含基于总时间的“热门查询”,而下半部分显示了使用结果分页的所有查询:


基于总时间的“热门查询”部分显示排名靠前的查询,以便最慢的查询可以在顶部显示。


包括:

  • 查询语句。

  • COUNT:该语句在日志中出现多少次。

  • 总时间:执行查询所需的时间,格式为 hh:mm:ss:ms。

  • 平均延迟:平均查询执行时间,格式为 hh:mm:ss:ms。

  • USER @ HOST:执行查询的用户及主机。


每条语句在查询数据最上方以条形图的形式显示,因此每个查询都对应唯一的颜色。


每个查询的总执行时间按照从左到右的方式显示,最慢的显示在最左边。条形图有助于快速评估每个慢查询语句间的对比。


在上图中,我们可以看到最慢的查询比所有其他慢查询时间的总和慢了好几个数量级。


单击某一行将显示对应慢查询的详细信息,例如查询首次和最后一次执行的时间点,查询所花费的最大时间:

MariaDB性能优化,我终于搞清楚了!_java_16

⑥Query 查询面板中的过滤设置


“查询”部分为我们提供了更完整的已分析查询列表,除了通过分页导航遍历所有查询外,还可以自定义过滤条件,从而将显示列表的内容缩小到我们感兴趣的范围。


过滤条件共有以下四种选项:

  • Containing:包含。

  • Not containing:不包含。

  • Matching regex:匹配的正则表达式。

  • Not matching regex:不匹配的正则表达式。


例如,将结果限制为匹配正则表达式“ sakila *”语句的过滤器:


通过单击标题,按任意列进行排序,箭头显示排序顺序(即升序,降序):

⑦以 CSV 形式导出


单击 Query 面板上的“Export as CSV”可以将查询数据保存到“.csv”文件中:


保存后的 CSV 文件可以通过 EXCEL 打开预览:

MariaDB性能优化,我终于搞清楚了!_java_17

总结


查询分析是用于分析数据库整体性能的有效技术,文中该技术采用了 MariaDB 服务器内置工具:Slow Query Log 慢查询日志和 Performance Schema 性能模式。


慢查询日志通过设置 long_query_time 全局系统变量值,来跟踪记录运行超时且存在问题的查询语句。


性能模式则是一个存储引擎,其中 Performance_schema 数据库,又由多个表组成,我们可以使用常规 SQL 语句查询这些表以获取更广泛的性能信息。


然而以上这两种工具都会产生大量的数据,引起繁琐的工作,Monyog 的引入为我们很好地解决此类问题,利用 Monyog 来监视 MariaDB 慢查询日志和性能模式是最有效的方法之一。