在MySQL8.0之后的创新版本中Explain扩展了新用法。
EXPLAIN INTO
当EXPLAIN FORMAT=JSON时支持额外的INTO用法,可以将JSON格式的输出保存到变量中,而不是将其返回给客户端。适用于任何可解释的语句(包含SELECT、TABLE、INSERT、UPDATE、REPLACE或DELETE语句)。之后使用JSON函数,从结果集中获取所需值,就像处理任何其他JSON值一样。这种用法可以实现对每个SQL的语句的执行计划的监控。足够应对执行计划突变得的场景,进一步进行优化。
如下实例:
mysql> EXPLAIN FORMAT=JSON INTO @myex SELECT * FROM employees LIMIT 1;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @myex;
+-------------------------------------------------------------------------------------+
| @myex |
+-------------------------------------------------------------------------------------+
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "30433.12"
},
"table": {
"table_name": "employees",
"access_type": "ALL",
"rows_examined_per_scan": 299335,
"rows_produced_per_join": 299335,
"filtered": "100.00",
"cost_info": {
"read_cost": "499.63",
"eval_cost": "29933.50",
"prefix_cost": "30433.13",
"data_read_per_join": "38M"
},
"used_columns": [
"emp_no",
"birth_date",
"first_name",
"last_name",
"gender",
"hire_date"
]
}
}
} |
+-------------------------------------------------------------------------------------+
#通过json函数,获取执行计划指标
mysql> SELECT JSON_EXTRACT(@myex, "$.query_block.cost_info.query_cost") AS query_cost,
JSON_EXTRACT(@myex, "$.query_block.table.access_type") AS select_ytpe ;
+------------+-------------+
| query_cost | select_ytpe |
+------------+-------------+
| "30527.49" | "ALL" |
+------------+-------------+
1 row in set (0.00 sec)
可以说是SQL语句监控优化的另一种捷径。
FOR SCHEMA
MySQL8.3支持FOR SCHEMA子句,这使得EXPLAIN的行为就像要分析的语句已经在命名数据库中执行一样。就是说不需要use 库名或则 库名.表名方式。提供更简便的访问方式。
语法如下:
schema_spec:
FOR {SCHEMA | DATABASE} schema_name
如下实例:
mysql> EXPLAIN FORMAT=TREE FOR SCHEMA employees SELECT * FROM employees LIMIT 1;
+-------------------------------------------------------------------------------------+
| EXPLAIN |
+-------------------------------------------------------------------------------------+
| -> Limit: 1 row(s) (cost=30527 rows=1)
-> Table scan on employees (cost=30527 rows=299335) |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
explain_json_format_version
MySQL 8.3支持两个版本的JSON输出格式,JSON输出格式的第2版基于访问路径。explain_json_format_version的值决定了所有使用它的explain语句所使用的json输出格式的版本。对比1版本,2版本的可读性更高。
自动SQL执行计划抓取
下面是通过PREPARE预处理和存储过程,进行执行计划的抓取。
#1.表结构
mysql> CREATE TABLE explain_outputs
(
id bigint not null AUTO_INCREMENT COMMENT '主键ID',
schema_name varchar(50),
query varchar(1000),
explain_output json,
create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 'cr time',
PRIMARY KEY(id)
);
#2.存储过程
mysql> DELIMITER //
CREATE PROCEDURE explain_query_for_schema(IN schema_name VARCHAR(64), IN query VARCHAR(1000))
BEGIN
SET @explain_stmt = CONCAT("EXPLAIN FORMAT=JSON INTO @explain_output FOR SCHEMA ", schema_name, " ", query);
PREPARE stmt FROM @explain_stmt;
EXECUTE stmt;
INSERT INTO explain_outputs (schema_name, query, explain_output) VALUES (schema_name, query, @explain_output);
END //
DELIMITER ;
#3.执行
mysql>SET @query = "select * from employees limit 1";
mysql>CALL explain_query_for_schema('employees',@query);
mysql>SET @query = "select * from employees where emp_no