10.9预览功能。支持SHOW ANALYZE和EXPLAIN FOR CONNECTION
作者 : Sergey Petrunia 2022-03-292022-03-29 发表评论: 10.9预览功能。支持SHOW ANALYZE和EXPLAIN FOR CONNECTION
显示分析(SHOW ANALYZE
如果你曾经需要使用MariaDB进行查询性能故障排除,你应该熟悉MariaDB的ANALYZE for statements功能。它的作用与其他一些数据库系统中的EXPLAIN ANALYZE相同。ANALYZE查询运行查询并产生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,预览版在这里可以看到
连接的解释
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。在这里下载预览版。