背景:

前几天我朋友问我一个问题,mysql的explan(执行计划)中type的index和all是不是压根没有区别,而且还推了几个博主的链接给我,我看了之后感觉有些无奈,有些博主自己都没有太搞清楚就出来科普让很多人都走歪道了,于是就有了这篇文章,花费了我一整天的时间(本文讨论的是innodb存储引擎)

mysql的explan:

什么是explan呢,相信看这篇文章的各位已经至少对mysql有了初步的了解,甚至在开发过程中也会用explan进行sql的优化,explan是mysql执行计划的关键词,在select前面加上这个关键字出现这条查询语句的执行过程,

会有以上关键词,
其中
id:选择标识符
select_type:表示查询的类型。
table:输出结果集的表
partitions:匹配的分区
type:表示表的连接类型
possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引
key_len:索引字段的长度
ref:列与索引的比较
rows:扫描出的行数(估算的行数)
filtered:按表条件过滤的行百分比
Extra:执行情况的描述和说明

本文不对其他属性做太多解释,这个只是带过一下,其中本文中我们要注意的主要是type中的属性效率
all<index<range<ref<ref_eq<const<system

我们做开发的时候一般都要求最低都要达到range的级别,range级别是范围索引。

mysql的索引底层:

在正文开始之前我们需要聊一下mysql索引底层和其他的一些原理,我们都知道mysql的innodb的底层是b+树(你都看到这里了,我默认你已经初步了解mysql底层了),b+树的特点是叶子节点存储数据,而非叶子节点存储的则是我们mysql的主键,所以每一次查到数据必定会查到最下面的叶子节点,所以mysql表的主树(主键所在的那棵树,也称聚簇索引)是一颗"矮胖的树

如上图,最下面一行就是数据库中主键对应的那列数据,上面的数字则是对应的主键,这是我们表的主树。mysql的主键也叫做聚簇索引(拿起笔这句话要记住)

磁盘页的概念:

我们都知道,mysql的瓶颈主要是磁盘io,为什么redis这种内存性数据库会流行呢,就是因为内存的IO比磁盘的IO高多了
,计算机存储系统中的数据库最小存储单位为512B,而我们磁盘每一次读取,用我们可以理解的"页"这个词来说,每一次磁盘io最小都为4kb,也就是说,你可能只需要读取1kb的数据,但是实际上操作系统确实帮你读取了至少4kb,就比如你在书本上翻页时,翻了一页之后那一页上只写了两行字,可这两行字的确是占了这满满的一页。(好了,操作系统的东西不扯远了。)

因为操作系统磁盘页的这一特性,所以我们b+树的节点大小也是4的倍数,这样也不会造成资源的浪费,b+树每一个节点大小为16kb,每读取一次节点为一次IO,而我们知道mysql的瓶颈就是IO,所以IO次数越少,效率越高。

回表:

我现在建一张表

CREATE TABLE user  (`id` int(11) NOT NULL AUTO_INCREMENT,`age` int(11) NULL,`name` varchar(255) NULL,PRIMARY KEY (`id`),INDEX `index_age`(`age`)
);

表中建了一个age的普通索引,现在我用执行计划以下这条sql查询,

EXPLAIN select * from user where age =8


每个表中每一个索引都有一课独立的树,但是表也不止一个索引啊,除了主键索引还有普通索引组合索引等等,不可能每颗树的叶子节点都是存放表数据吧,那也太浪费我们的磁盘资源了,所以非聚餐索引树最每个索引所对应的是该表的聚餐索引。
如果你是新手,不太看得懂,那么接下来我们再看看这条sql实际上在mysql的执行过程的图形化展示,

如上图所示,在用了这条sql的因为用到了索引的缘故,mysql回到age普通索引树中查到age为8的聚簇索引,然后再到聚簇索引所在的树中查询那条记录,这个过程叫做回表。

覆盖索引:

看到这里的时候有人就发现了:“回表多经历了一课树,多浪费了几次IO的过程,所以用聚餐索引树查的效率就一定要更高,因为IO次数要少”,那可不一定,
接下来我们再用一条sql

EXPLAIN select * from user where age =8

结果依然是使用了我们的“index_age”普通索引,为什么会这样呢,这就要归功我们mysql的优化器,优化器会根据算法帮你选择最优的索引,我们的index_age索引树中已经包含了id主键,我们的查询已经拿到了需要拿到的数据,那么就不需要再去浪费IO回表,这个过程叫做覆盖索引,
如在Extra列看到Using index,说明正在使用覆盖索引。

原因分析:

有了以上的基础,我们再来谈谈type中index和all的区别就好很多了,这是我在网上看到的其他博主的解答

而且大多数博主都认为index和all没有实际意义的区别认为只是跟着索引全表访问了一下而已。效率一样,这一点我不敢苟同,虽然all和index都是很慢的一种type,我们应该对其优化,但是因为此所以导致很多人都忽视了他们两者的区别。

论证:

CREATE TABLE `user` (`id` int(255) NOT NULL AUTO_INCREMENT COMMENT '用户编号',`duankou` int(255) DEFAULT NULL COMMENT '端口号',`name` varchar(255) NOT NULL COMMENT '用户名字',`vx` varchar(255) DEFAULT NULL COMMENT '微信',`endTime` date DEFAULT NULL COMMENT '用户到期时间',`password` varchar(255) NOT NULL COMMENT '密码',`canshu` varchar(255) DEFAULT NULL COMMENT '其他参数,不填则默认',`beizhu` varchar(255) DEFAULT NULL COMMENT '备注,可以没有',`youxiang` varchar(255) DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (`id`),KEY `nameIndex` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;

我建立了一张表,并且在表中增加了一条普通索引,且在其中添加了三百万条数据

select count(*) from user


用count(*) 的查询方式查询时间是0.6秒左右
再用explan来看看,他用的是哪个索引


可以看到其实我们经常使用的count(*)他其实也是被mysql的优化器优化,找了一个非聚簇索引树去查找,而并不是去找主键所在的那颗局促索引树.这样的好处是啥呢,因为前面我们讲过,数据库磁盘最大的瓶颈是IO,聚簇索引树因为叶子节点存储了数据的缘故,所以所占的磁盘也会更大,而非聚簇索引树的叶子节点仅仅只是存储了主键,而每一个节点同样是16kb的空间,聚簇索引树的叶子可能只能存储一千条记录,而非聚簇索引树却可以存上万条,所以我们的优化器会选择去非聚簇索引树查找,节省IO资源

接下来我们看看聚簇索引树的效率


我count了一个没有建立索引的字段,时间是0.97秒,慢了二分之一左右,
再用explain看看

type 是all,并没有使用到索引,而他们都是查询了count()所有的记录数量,而“youxiang”这个字段却是直接读取了聚簇索引树,因为IO的问题,所以"youxiang"字段显得慢很多,小伙伴们,现在懂了吗

史上最详细的mysql底层和explan type和type中index和all的区别相关推荐

  1. 史上最详细的MySQL操作事例

    史上最详细的MySQL操作事例 文章目录 史上最详细的MySQL操作事例 一.数据库的操作 二.数据表的操作 三.数据表的增删查该 四.数据准备 五.条件查询 六.排序 七.聚合函数 八.分组 九.分 ...

  2. 史上最详细 Lipreading using Temporal Convolutional Networks 环境配置

    唇语识别是目前人工智能领域比较热门的应用之一,本文将在之后的内容中介绍2020年英文词汇级唇语识别在LRW(Lir Reading in the Wild)数据集以及LRW-1000两个数据集上实现S ...

  3. 全网史上最详细全面的Linux下安装mysql客户端服务端

    全网史上最详细全面的Linux下安装mysql客户端服务端Linux下安装mysql 1.上传MySQL5.6的tar包 创建目录: mkdir /usr/local/src/mysql5.6 上传: ...

  4. 史上最详细、最良心的MySQL 5.7 + Navicat 下载安装教程(附安装包)

    这怕是史上最详细,最良心的MySQL5.7下载安装教程了,文末还有Navicat下载安装加破解的教程. 一.下载 1.可以去官网下载:https://dev.mysql.com/downloads/m ...

  5. 吐血总结|史上最全的MySQL学习资料!!

    在日常工作与学习中,无论是开发.运维.还是测试,对于数据库的学习是不可避免的,同时也是日常工作的必备技术之一.在互联网公司,开源产品线比较多,互联网企业所用的数据库占比较重的还是MySQL. 在刚刚出 ...

  6. Mysql数据库的简单备份与还原_史上最简单的MySQL数据备份与还原教程

    本文主要为大家详细介绍了史上最简单的MySQL数据备份与还原教程第一篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家. 数据备份与还原第一篇分享给大家,具体内容如下 基础概念: ...

  7. 史上最详细MySQL5.5复制配置步骤,与以前版本的有所不同

    史上最详细MySQL5.5复制配置步骤,与以前版本的有所不同 http://codingstandards.iteye.com/blog/1535994 操作系统:CentOS 5.8 MySQL版本 ...

  8. 自学软件测试怎么学?【史上最详细学习路线】(附全套资料)

    对于想入行学软件测试的新手来说,首先需要一个高效的学习线路图,还要有全套的学习资料,两者结合才能有最好的学习效果. 授人以鱼不如授人以渔,所以今天我也想把我的经验和经历分享给大家,史上最详细的软件测试 ...

  9. 史上最详细的LXR安装介绍

    史上最详细的LXR安装介绍(Ubuntu14.04+Apache2.4.7) 简介: LXR (Linux Cross Reference)是一个通过交叉索引方便用户查看项目源代码的工具.项目地址:h ...

最新文章

  1. php类退出魔术方法,php类中常用的魔术方法
  2. JavaScript之作用域链
  3. 基因突变不是随机的?!Nature最新论文挑战进化论
  4. 第六章 模型的验证、监控与调优
  5. Hyperledger Fabric 核心模块(4)orderer 共识
  6. Spark on K8S 的最佳实践和需要注意的坑
  7. css复选框样式_使用CSS样式复选框
  8. 首次push本地代码到github上出现的问题及解决方案
  9. 13.追我的男生辣么多
  10. C# 读取Excel表格中的数据
  11. 黄聪:C#使用能够foreach对hashtable、List遍历时“集合已修改;可能无法执行枚举操作。”错误...
  12. jad反编译成java,反编译工具jad的使用(将*.class文件变成*.java文件,附带jad.zip包)...
  13. 《大数据之路:阿里巴巴大数据实践》-第1篇 数据技术篇 -第5章 实时技术
  14. 糗百文化:糗事百科的运营哲学
  15. 怎样配置外汇ea服务器运行,外汇EA安装及使用超详细说明-EA邦
  16. Delphi 编译的程序在win10中怎样默认以管理员身份运行
  17. 基于51单片机的555定时器测电容proteus仿真
  18. 你的工作表现是否成熟,用这4条检验自己
  19. 什么是政微助手?政微助手是干什么用的?
  20. 介绍分享几款免费的在线Web文件管理器

热门文章

  1. 爱库存+爱乐奇+齐家网,案例+原理+实践,大神讲透混合云安全|上海技术活动...
  2. css实现六边形图片
  3. chemi.ren让你停车无忧,做你的贴心车秘书
  4. 基于php+mysql的医保管理系统
  5. Google Voice注册及初步体验
  6. 通过xshell从Linux服务器下载文件夹
  7. 盒子模型——padding
  8. Echarts渲染行政区划,实现聚焦高亮交互
  9. 【商业分析】FinTech之支付宝 • 数字生活开放平台
  10. POJ 1664 /NYOJ 758 放苹果问题(递归)