使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析查询语句
在 SELECT 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL
参考文档:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
--示例表
DROP TABLE IF EXISTS `system_encryption_user`;
CREATE TABLE `system_encryption_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`login_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录名',`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'email',`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',`mobilephone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '手机',`phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '固定电话',`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户密码',`company_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '所属分公司',`dept` int(10) NULL DEFAULT NULL COMMENT '所属部门',`is_delete` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 445 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;INSERT INTO `system_encryption_user` VALUES (1, 'superAdmin', 'Zsxxxxxx@163.com', '超级管理员', '12345678910', '12345678910', '$2a$10$UUZGvFdSju3/kT6H7lMmF.', NULL, 0);DROP TABLE IF EXISTS `system_encryption_role`;
CREATE TABLE `system_encryption_role` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id ',`role_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '角色名称',`role_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '角色描述',PRIMARY KEY (`id`) USING BTREE,INDEX `index_name`(`role_name`(191)) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;INSERT INTO `system_encryption_role` VALUES (1, 'SUPERADMIN', '超级管理员');DROP TABLE IF EXISTS `system_encryption_user_role`;
CREATE TABLE `system_encryption_user_role` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`user_id` int(11) NULL DEFAULT NULL COMMENT '用户id',`role_id` int(11) NULL DEFAULT NULL COMMENT '角色id',PRIMARY KEY (`id`) USING BTREE,INDEX `index_user_role`(`user_id`, `role_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 411 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of system_encryption_user_role
-- ----------------------------
INSERT INTO `system_encryption_user_role` VALUES (1, 1, 1);
EXPLAIN SELECT * FROM system_encryption_user WHERE id=1;

id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的。
id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。
select_type 表示对应的是简单的还是复杂的查询
simple 简单查询 查询不包含子查询和union
EXPLAIN SELECT * FROM system_encryption_user WHERE id=1;

primary 复杂查询中最外层的SELECT
subquery 包含在SELECT 中子查询(不在from子句中)
derived 包含在from子句中的子查询 临时表也称为(衍生表或者派生表)
-- 关闭mysql 5.7 版本对衍生表的优化
set session optimizer_switch='derived_merge=off';EXPLAIN SELECT (SELECT 1 FROM system_encryption_user WHERE id=1) FROM (SELECT * FROM system_encryption_user WHERE id=1) exp 
在 union 中的第二个和随后的 select
-- 恢复
set session optimizer_switch='derived_merge=on';
EXPLAIN SELECT * FROM system_encryption_user UNION ALL SELECT * FROM system_encryption_user 
表示Explain优化器正在访问哪个表
如果查询是基于分区表的话,partitions 字段会显示查询将访问的分区。