MySQL explain Type总结

Posted bladestone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL explain Type总结相关的知识,希望对你有一定的参考价值。

explain

在调试优化mysql中,大家都需要使用explain查看SQL执行计划,其中的字段信息在本文中将逐一详述。

基本信息

DB: shopping.shool_info

CREATE TABLE `school_info` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '学院名称',
  `student_num` int DEFAULT NULL COMMENT '学生数量',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `created_by` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '创建人',
  `updated_by` varchar(30) COLLATE utf8_unicode_ci NOT NULL COMMENT '更新人',
  `updated_at` datetime NOT NULL COMMENT '更新时间',
  `valid` smallint NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idnew_table_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

常见的扫描方式:

  • system:系统表,少量数据,往往不需要进行磁盘IO
  • const:常量连接
  • eq_ref:主键索引(primary key)或者非空唯一索引(unique not null)等值扫描
  • ref:非主键非唯一索引等值扫描
  • range:范围扫描
  • index:索引树扫描
  • ALL:全表扫描(full table scan)

type扫描方式由快到慢

system > const > eq_ref > ref > range > index > ALL

示例

const


基于主键直接命中,一次就找到数据,其查询效果为const。
应用场景: 命中PK 或者 unique Key,其type和ref为const

eq_ref

explain select * from school_info school left join class_info cls on school.id = cls.school_id where school.id = cls.school_id
上例中对于前表school_info表中的每一行(row),对应后class_info表有2行被扫描.
场景:

  1. 联表(join)查询
  2. 命中主键(primary key)或者非空唯一索引(unique not null)
  3. 等值连接

eq_ref

新建表:

CREATE TABLE `class_info_index` (
  `id` bigint NOT NULL,
  `school_id` bigint NOT NULL,
  `name` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `course_num` int DEFAULT '0',
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `created_by` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT '',
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_by` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT '',
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

表只有单独index,没主键。

explain select * from school_info school left join class_info_index cls on school.id = cls.school_id where school.id = cls.school_id;
由于后表使用了普通非唯一索引,对于前表的每一行(row),后表可能有多于一行的数据被扫描.

单表查询:

explain select * from class_info_index where id = 1;

当id改为普通非唯一索引后,常量的连接查询,也由const降级为了ref,因为非唯一索引所以有多于一行的数据被可能被扫描

ref每一次匹配可能有多行数据返回,虽然它比eq_ref要慢,但它仍然是一个很快的join类型

场景: 联表查询 普通非唯一索引

range

between:

explain select * from school_info where id between 3 and 9;
如果是用非索引字段,在between中,将进行全表扫描。
in,>,>=,<,<=
explain select * from school_info where id >4;
range比较好理解,它是索引上的范围查询,它会在索引上扫码特定范围内的值

index

explain select count(*) from school_info
index类型,需要扫描索引上的全部数据,它仅比全表扫描快一点

All

explain select count(*) from school_info where student_num>100;
如果id上不建索引,则全表扫描

总结

system > const > eq_ref > ref > range > index > ALL

大家注意掌握上述的MySQL索引顺序,效率从高到低。

以上是关于MySQL explain Type总结的主要内容,如果未能解决你的问题,请参考以下文章

MySQL explain Type总结

MySQL explain Type总结

MySQL explain Type总结

MySQL中explain的type类型

MySQL中explain的type类型

在Mysql中遇到关于区间范围内的索引优化