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行被扫描.
场景:
- 联表(join)查询
- 命中主键(primary key)或者非空唯一索引(unique not null)
- 等值连接
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总结的主要内容,如果未能解决你的问题,请参考以下文章