mysql的explain笔记

本文目录

  • 1. explain的作用
  • 2. explain的用法
    • 2.1 字段id
    • 2.2 字段select_type
    • 2.3 字段table
    • 2.4 字段partitions
    • 2.5 字段type
    • 2.6 字段possible_keys
    • 2.7 字段key
    • 2.8 字段key_len
    • 2.9 字段ref
    • 2.10 字段rows
    • 2.11 字段filtered
    • 2.12 字段Extra
  • 3. sql文件
  • 4. 参考

1. explain的作用

explain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句。explain主要用于分析查询语句或表结构的性能瓶颈。

2. explain的用法

在正常执行的sql语句前加上explain就可以分析改sql语句的执行效率。
mysql的explain笔记_第1张图片
本文表结构和数据(文末有sql文件):
mysql的explain笔记_第2张图片

2.1 字段id

字段id表示语句执行的序列号,数值越大优先级越高,同级的情况下,从上往下执行。
mysql的explain笔记_第3张图片
这个例子经常用来解释字段id,但是我在mysql8.0版本里面并没有看到其他博客的执行效果。有可能是版本的原因,读者要是知道原因,欢迎留言,不甚感谢。
mysql的explain笔记_第4张图片
这里,我是用left join 来解释字段id。
mysql的explain笔记_第5张图片
可以看到这个sql先是执行外面的 select * from student st, 然后遇到了left join再去执行了后面的语句,当然后后面的语句会先执行完。

2.2 字段select_type

  • SIMPLE 简单的select查询,查询中不包含子查询或者UNION
  • PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY
  • SUBQUERY 在SELECT或WHERE列表中包含了子查询
  • DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,把结果放在临时表中
  • UNION 若第二个SELECT出现在UNION之后,则被标记为UNION:若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED
  • UNION RESULT 从UNION表获取结果的SELECT

2.3 字段table

当前执行的表

2.4 字段partitions

查询是基于分区表的话,会显示查询将访问的分区

2.5 字段type

依次从最优到最差分别为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
官方文档

  • const, system:mysql能对查询的某部分进行优化并将其转化成一个常量(可以看show warnings 的结果)。用于 primary key 或 unique key 的所有列与常数比较时,所以表最多有一个匹配行,读取1次,速度比较快
  • eq_ref:primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。这可能是在 const 之外最好的联接类型了,简单的 select 查询不会出现这种 type。
  • ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。
  • ref_or_null:类似ref,但是可以搜索值为NULL的行。
  • index_merge:表示使用了索引合并的优化方法。
  • range:范围扫描通常出现在 in(), between ,> ,<, >= 等操作中。使用一个索引来检索给定范围的行。
  • index:和ALL一样,不同就是mysql只需扫描索引树,这通常比ALL快一些。
  • ALL:即全表扫描,意味着mysql需要从头到尾去查找所需要的行。通常情况下这需要增加索引来进行优化了

2.6 字段possible_keys

查询可能使用哪些索引来查找。

2.7 字段key

查询实际上使用哪些索引来查找。

2.8 字段key_len

该key_len列指示MySQL决定使用的密钥的长度。的值 key_len使您能够确定MySQL实际使用的多部分键的多少部分。如果该key列显示 NULL,则该key_len 列也显示NULL。在不损失精确性的情况下,长度越短越好。

2.9 字段ref

显示索引的那一列被使用了,如果可能的话,最好是一个常数。哪些列或常量被用于查找索引列上的值。

2.10 字段rows

根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,也就是说,用的越少越好

2.11 字段filtered

该filtered列指示将被表条件过滤的表行的估计百分比。最大值为100,这表示未过滤行。值从100减小表示过滤量增加。 rows显示检查的估计行数,rows× filtered显示将与下表连接的行数。例如,如果 rows为1000且 filtered为50.00(50%),则与下表连接的行数为1000×50%= 500。

2.12 字段Extra

此列包含有关MySQL如何解析查询的其他信息。

3. sql文件

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `studentName` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '小明', '18');
INSERT INTO `student` VALUES ('2', '小黄', '19');
INSERT INTO `student` VALUES ('3', '小红', '19');

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `id` int(11) NOT NULL,
  `courseName` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', 'math');
INSERT INTO `course` VALUES ('2', 'english');

-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `id` int(11) NOT NULL,
  `studentId` int(11) DEFAULT NULL,
  `courseId` int(11) DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES ('1', '1', '1', '100');
INSERT INTO `score` VALUES ('2', '1', '2', '99');
INSERT INTO `score` VALUES ('3', '2', '1', '99');
INSERT INTO `score` VALUES ('4', '2', '2', '98');

4. 参考

mysql8.0官方文档-explain
butterfly博客

你可能感兴趣的:(太极拳——数据库)