Query Profiling,即查询分析技术,是 MySQL 数据库提供的一种诊断 SQL 性能的方法,同时也被视为分析数据库整体性能的有效技术。
用户可以在开启 Profiling 的情况下,查看当前会话中 SQL 执行时间消耗分布,系统时间,CPU 用户时间,以及过程中涉及到的关键函数在源代码文件中的定位等。
由于单个大中型应用程序可以在单位时间内完成多个查询,因此 Query Profiling 是数据库优化调整的重要组成部分,它既可作为数据库性能优化的积极主动措施,亦可用于诊当前断数据库性能是否存在问题。
在实际工作场景中,如果不采用可靠的查询分析技术,相关技术人员往往很难定位数据库中性能瓶颈及性能不佳问题的根源所在。
作为 MySQL 的一个分支,MariaDB Server 自带的内置工具中为我们提供了 Query Profiling 相关的查询概要分析技术。
我们以 Slow Query Log(慢速查询日志)和 Performance Schema(性能策略模型)这两类 MariaDB Server 内置工具为例,深入探索查询分析技术的价值。
首先让我们来回顾一下 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,添加了存储引擎,新功能等,性能方面也做了相应改进。
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
以上设置在服务器重启后生效。
已写入文件的慢查询日志可以通过任何文本编辑器打开进行查看,下面是一则慢查询日志的示例内容:
通过文本编辑器来查看慢查询日志看似非常方便,但随着日志内容(数据量)的增长,很可能存在内容丢失的情况。
即显示不完整,这是由于文本编辑器自身无法承载越来越大的日志容量,而造成日志中部分内容解析缺失的风险。
为了避免这类情况的发生,MariaDB 为我们提供了 mysqldumpslow 工具,该工具可以通过汇总信息来简化过程,从而更可靠且有效地展示日志内容。
“mysqldumpslow”的可执行文件与 MariaDB 是捆绑在一起的,所以只需通过命令行将需要显示的日志路径传递给它即可。
从下面的 Demo 中可以获悉,通过“mysqldumpslow”呈现的日志内容可读性更强,并且还支持分组显示。
“mysqldumpslow”命令可以通过指定不同的参数来定制化输出格式,如下示例中将显示按平均查询时间排序的前 5 个查询:
[ mysqldumpslow -t 5 -s at /var/log/mysql/localhost-slow.log ]
如果你对上述 log 日志中显示的内容不熟悉,可以结合 slow_log 表来帮助理解。
如下是日志中每个字段对应的详情描述:
下图所示是针对 slow_log 表的 SELECT ALL 示例结果:
还可以通过 slow_log 表来模拟 Linux 的“ tail -100 log-slow.log”命令,列出最新查询记录(最后 100 个查询),如下图所示:
为了方便日后频繁调用,我们也可以专门创建一个存储过程(如SHOW_LATEST_SLOW_QUERIES),需要显示的查询个数可以通过输入参数传递给这个存储过程。
这样一来当我们需要列出指定数量的查询记录时,就不需要每次都重复键入相同的 SELECT 语句了。
为了更有效地在生产环境中获取我们想要的慢查询日志信息,通常情况下,我们需要做一些设置,例如规定哪些查询必须被写入 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 语句会被记录到慢日志中:
通过 Performance Schema 进行查询分析
我们可以通过另一种服务器性能工具 Performance Schema 来监视服务器性能。
Performance Schema 是 MariaDB 5.5 中被引入的,以存储引擎的方式实现;因此,在 MariaDB 的存储引擎列表中可以找到 Performance Schema。
图中的“Performance Schema”的功能默认情况下是禁用的,
我们可以通过如下设置逐一开启:
①在 my.cnf 或 my.ini 文件的 [mysqld] 部分中添加以下行:
需要注意的是,“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”来禁用检测。
通过更新 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_%';
在缩小了感兴趣的范围后,有两种方法可以进行监控:
下面我们以查看原始摘要数据为例: