本文转载自[1],对[1]进行了整理

explain结果中的type字段列表:

type字段取值  说明 SQL示范 扫描条件 建表特点
system 系统表,少量数据,往往不需要进行磁盘IO; explain select * from mysql.time_zone;

这些数据已经加载到内存里,不需要进行磁盘IO。

这类扫描是速度最快的。

带主键
const 常量连接

explain select * from (select * from user where id=1) tmp;(system+const)

explain select * from user where id=1;(const)

(1)命中主键(primary key)或者唯一(unique)索引;

(2)被连接的部分是一个常量(const)值;

带主键
eq_ref 主键索引(primary key)或者非空唯一索引(unique not null)等值扫描 explain select * from user,user_ex where user.id=user_ex.id;(All+eq_ref)
 

对于前表的每一行(row),后表只有一行被扫描。

再细化一点:

(1)join查询;

(2)命中主键(primary key)或者非空唯一(unique not null)索引;

(3)等值连接;

含主键
ref 非主键非唯一索引等值扫描

explain select * from user,user_ex where user.id=user_ex.id;(All+ref)

--------------------------------------------

explain select * from user where id=1;

把上例eq_ref案例中的主键索引,改为普通非唯一(non unique)索引。

-----------

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

*********

ref扫描,可能出现在join里,也可能出现在单表普通索引里,每一次匹配可能有多行数据返回,虽然它比eq_ref要慢,但它仍然是一个很快的join类型。

无主键,含普通索引
range 范围扫描

explain select * from user where id between 1 and 4;

explain select * from user where id in(1,2,3);

explain select * from user where id>3;

像上例中的between,in,>都是典型的范围(range)查询。

画外音:必须是索引,否则不能批量"跳过"。

含主键
index 索引树扫描 explain select count(*) from type_learn.user;
 

需要扫描索引上的全部数据

id是主键,该count查询需要通过扫描索引上的全部数据来计数。

画外音:此表为InnoDB引擎。

它仅比全表扫描快一点。

含主键
ALL 全表扫描(full table scan) explain select * from user,user_ex where user.id=user_ex.id;(ALL+ALL) 如果id上不建索引,对于前表的每一行(row),后表都要被全表扫描。 无主键

上面各类扫描方式由快到慢

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

#-------------------------------------------------------------------------------------------------------------------

为type=const创建数据:

mysql> create database type_learn;

mysql> create table user (id int primary key,name varchar(20))engine=innodb;

mysql> insert into user values(1,'shenjian');

mysql> insert into user values(2,'zhangsan');

mysql> insert into user values(3,'lisi');

#-------------------------------------------------------------------------------------------------------------------

为type=eq_ref创建数据:

create table user (id int primary key,name varchar(20))engine=innodb;
insert into user values(1,'shenjian');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
create table user_ex (id int primary key,age int)engine=innodb;
insert into user_ex values(1,18);
insert into user_ex values(2,20);
insert into user_ex values(3,30);
insert into user_ex values(4,40);
insert into user_ex values(5,50);

eq_ref用于联表查询的情况

#-------------------------------------------------------------------------------------------------------------------

为type=ref创建数据:

create table user (id int,name varchar(20) ,index(id))engine=innodb;
insert into user values(1,'shenjian');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
create table user_ex (id int,age int,index(id))engine=innodb;
insert into user_ex values(1,18);
insert into user_ex values(2,20);
insert into user_ex values(3,30);
insert into user_ex values(4,40);
insert into user_ex values(5,50);

这里的index(id)是增加普通索引,普通索引不是主键索引

主键索引的叶子结点存放了整行记录,普通索引的叶子结点存放了主键ID,查询的时候需要做一次回表查询
一定要回表查询么?
不一定,当查询的字段刚好是索引的字段或者索引的一部分,就可以不用回表,这也是索引覆盖的原理

#-------------------------------------------------------------------------------------------------------------------

为type=range,index创建数据:

create table user (id int primary key,name varchar(20))engine=innodb;

insert into user values(1,'shenjian');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');
insert into user values(5,'zhaoliu');

#-------------------------------------------------------------------------------------------------------------------

为type=ALL创建数据:

create table user (id int,name varchar(20))engine=innodb;
insert into user values(1,'shenjian');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
create table user_ex (id int,age int)engine=innodb;
insert into user_ex values(1,18);
insert into user_ex values(2,20);
insert into user_ex values(3,30);
insert into user_ex values(4,40);
insert into user_ex values(5,50);

#-------------------------------------------------------------------------------------------------------------------

建立正确的索引,对数据库性能的提升很重要。

总结

各类扫描类型的要点是:

  • system最快:不进行磁盘IO

  • const:PK或者unique上的等值查询

  • eq_ref:PK或者unique上的join查询,等值匹配,对于前表的每一行(row),后表只有一行命中

  • ref:非唯一索引,等值匹配,可能有多行命中

  • range:索引上的范围扫描,例如:between/in/>

  • index:索引上的全集扫描,例如:InnoDB的count

  • ALL最慢:全表扫描(full table scan)

(4)建立正确的索引(index),非常重要;

(5)使用explain了解并优化执行计划,非常重要;

Reference:

[1]同一个SQL语句,为啥性能差异咋就这么大呢?(1分钟系列)

[2]主键索引和普通索引的区别

mysql的explain中type取值与SQL性能优化的关系相关推荐

  1. 汇编语言-016(SCASB 、STOSB 、LODSD 、数组中的取值、二维数组操作、冒泡排序和二分查找、CMPSW )

    1: SCASB : (字节)将AL的值与EDI寻址的一个字比较.进行在一个字符串检索特定的字符 .386 .model flat,stdcall.stack 4096 ExitProcess PRO ...

  2. oracle sql为null值,在SQL Server Oracle MySQL当数据库中查出某值为NULL怎么办

    在SQL Server Oracle MySQL当数据库中查出某值为NULL怎么办? 1.MSSQL: ISNULL() 语法 ISNULL ( check_expression , replacem ...

  3. 从多个Word文档中批量取值,整理到Excel表中。

    针对多个内部是表格,并且格式相同的文档,例如:一些Word表格简历.一些调查表.技术交底等.可以一键提取所有文档中固定位置的数据. 按位置提取word文档内容到excel 通常我们要重复提取每个文档中 ...

  4. python权重是什么意思_在python带权重的列表中随机取值的方法

    1 random.choice python random模块的choice方法随机选择某个元素 foo = ['a', 'b', 'c', 'd', 'e'] from random import ...

  5. 从多个Word文档中批量取值,整理到Excel表中的技能,整理简历者必备

    从多个Word文档中批量取值,整理到Excel表中的技能,整 从多个Word文件中提取指定的值到Excel中,也可以理解为把多个Word文件的值放在一个表格中,便于统计或查阅. 本教材提供了4种不同情 ...

  6. Python中字典取值常用的方法!

    字典是Python中比较常见的数据类型之一,它是一种可变容器模型,可以存储任意数量的任意类型的数据,而且字典中的每个元素由一个键和一个值组成,键和值之间用冒号分隔.本文为大家介绍一下Python中字典 ...

  7. java enumerator_java 中遍历取值异常(Hashtable Enumerator)解决办法

    java 中遍历取值异常(Hashtable Enumerator)解决办法 用迭代器取值时抛出的异常:java.util.NoSuchElementException: Hashtable Enum ...

  8. java中integer的范围_java中integer取值范围是什么

    java中integer取值范围是什么 发布时间:2020-08-27 10:01:14 来源:亿速云 阅读:69 作者:小新 这篇文章给大家分享的是有关java中integer取值范围是什么的内容. ...

  9. mysql 大量数据 更改索引_一文看懂ICP原理--MySQL用索引去表里取数据的一种优化...

    概述 今天主要介绍一下mysql的ICP特性,可能很多人都没听过,这里用一个实验来帮助大家加深一下理解. 一.Index_Condition_Pushdown Index Condition Push ...

最新文章

  1. SQL Server误区30日谈-Day21-数据损坏可以通过重启SQL Server来修复
  2. 2019 阿里云峰会·北京站正式启动,互联网出海分论坛报名开启...
  3. ABAP 的历史,现在,和未来的讨论
  4. ajax 请求post和get,ajax请求get和post
  5. Alpha 答辩总结
  6. 科大讯飞新一代语音识别系统揭秘
  7. ARM通用寄存器和特殊寄存器
  8. 使用 ASP.NET 2.0 ObjectDataSource 控件(整理自msdn)
  9. 拓端tecdat|R语言有状态依赖强度的非线性、多变量跳跃扩散过程模型似然推断分析股票价格波动
  10. 一图精通python3
  11. ZZNUOJ_用C语言编写程序实现1236:数的逆转(附完整源码)
  12. 数仓理论知识之什么是度量,什么是粒度,什么是事实,什么是维度
  13. 小技巧-不使用js制作高级足球比赛赛程表
  14. 【教程】手机远程连接另一台手机的termux进行拍照
  15. Android入门小项目--微信登录界面源码(倒计时、fragement切换、activity信息传递)
  16. ABAP基本数据类型
  17. LINUX——账号和权限管理
  18. PBC下载、安装及基本使用
  19. echarts 获取点击的y轴数值_四川Y轴前后钢板防护罩哪里卖
  20. CGED2020总结

热门文章

  1. linux apache添加多站点配置(Ubuntn和Centos)
  2. Tomcat/weblogic session失效时间的几种设置方法
  3. 男人25岁,别让“努力“毁了你的辉煌
  4. JS原生封装时间函数 日期格式过滤
  5. Vue watch如何同时监听多个属性?
  6. 在ElementUI中改变el-table中的el-table-column样式
  7. mysql 商品属性_MySQL产品属性表设计
  8. java main test_java调用main自动执行testng方法一
  9. vue页面引入多个组件的方法
  10. svn cvs git的区别