10.9 预览功能:支持 SHOW ANALYZE 和 EXPLAIN FOR CONNECTION

SHOW ANALYZE
如果您曾在 MariaDB 中进行查询性能故障排除,您应该熟悉 MariaDB 的语句 ANALYZE 功能。它与某些其他数据库系统中的 EXPLAIN ANALYZE 功能类似:ANALYZE query 会运行该query并生成 EXPLAIN 输出,并补充查询执行数据
ANALYZE SELECT *
FROM orders, customer
WHERE
customer.c_custkey = orders.o_custkey AND
customer.c_acctbal < 0 AND
orders.o_totalprice > 200*1000
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | r_rows | filtered | r_filtered | Extra |
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
| 1 | SIMPLE | customer | ALL | PRIMARY,... | NULL | NULL | NULL | 149095 | 150000 | 18.08 | 9.13 | Using where |
| 1 | SIMPLE | orders | ref | i_o_custkey | i_o_custkey | 5 | customer.c_custkey | 7 | 10 | 100.00 | 30.03 | Using where |
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
还有 ANALYZE FORMAT=JSON 变体,它提供更多信息:它生成 EXPLAIN FORMAT=JSON 输出,并补充观察到的运行时统计信息。统计信息字段以“r_”开头
- “r_loops” 显示每个查询计划元素执行了多少次
- “r_rows” 显示平均产生了多少行
- “r_total_time_ms” 显示每个查询计划元素花费了多少时间
我们在 MariaDB 一直使用 ANALYZE FORMAT=JSON 来诊断查询优化器问题,并且它已被证明非常有用。但在某些时候,我们遇到了一个有趣的障碍。我们分析的查询变得越来越大,最终查询性能问题是关于那些永远无法完成的长达一页的查询。
由于查询永远无法完成,因此您无法获取该查询的 ANALYZE [FORMAT=JSON] 输出。
MariaDB 具有 SHOW EXPLAIN 命令。它显示当前正在运行的查询的 EXPLAIN 输出。因此,我们决定将这些命令结合起来,并引入了 SHOW ANALYZE 命令。新命令的语法是
SHOW ANALYZE [FORMAT=JSON] FOR <connection_id>;
对于 FORMAT=JSON 变体,输出类似于 ANALYZE [FORMAT=JSON] 输出。r_ 成员显示截至目前已发生的执行统计信息。还有一个额外的成员 r_query_time_in_progress_ms,它显示查询已运行了多长时间
MariaDB [test]> show analyze format=json for 4\G
*************************** 1. row ***************************
SHOW ANALYZE: {
"r_query_time_in_progress_ms": 1716,
"query_block": {
"select_id": 1,
"r_loops": 1,
"nested_loop": [
{
"table": {
"table_name": "customer",
"access_type": "ALL",
"r_loops": 1,
"rows": 1500,
"r_rows": 273,
....
其他 r_* 成员的存在取决于执行器是否正在收集目标查询的计时信息。
如果目标查询是 ANALYZE 查询,执行器将为其收集计时信息(这会产生一些额外的 CPU 开销)。然后,SHOW ANALYZE FORMAT=JSON 将显示 r_*time_ms 成员。
如果目标查询是常规查询(如 SELECT、UPDATE、DELETE 等),则执行器将不会收集计时信息,并且 SHOW ANALYZE FORMAT=JSON 将仅显示基于计数的统计信息,例如 r_loops、r_rows 和 r_filtered。
此功能的 JIRA 任务是 MDEV-27021,预览版可在此处获取
EXPLAIN FOR CONNECTION
MariaDB 和 MySQL 都具备检查正在运行的查询的查询计划的能力。MariaDB 最早引入了此功能,并使用以下语法
EXPLAIN [FORMAT=JSON|...] FOR CONNECTION <connection_id>;
请注意,MySQL 允许生成 JSON 输出,其中包含更多详细信息。社区多次要求在 MariaDB 中添加对 MySQL 语法的支持。我们已实现了这一点,并添加了对生成 FORMAT=JSON 输出的支持。现在,在 10.9 预览版中,可以使用以下任一形式的语法
SHOW EXPLAIN [FORMAT=JSON] FOR <connection_id>;
EXPLAIN [FORMAT=JSON] FOR CONNECTION <connection_id>;
此功能的 JIRA 任务是 MDEV-10000。在此处下载预览版。