在 InnoDB 中,从二级索引回到主键索引查询数据,这个过程称作回表过程,而且这个回表过程是可以被优化的,这个优化就是利用覆盖索引。

先说结论,如果一个索引的字段包含了所有要查询的字段,这个索引就称作覆盖索引,覆盖索引可以减少回表过程,能有效提高查询效率。

前面我们有说过,在 InnoDB 中数据都是保存在 B+ 树上,主键索引保存了整行记录,二级索引保存了主键的值。

一次查询操作,要么是遍历主键索引,要么是遍历二级索引,要么就是先遍历二级索引得到主键 id 的值,然后再到主键索引上通过主键 id 查找满足要求的记录。

如果只遍历一次 B+ 树就能获取到我们要的数据,即没有回表过程,这个效率显然是不错的,这就是覆盖索引的优势。下面看个具体的例子。

mysql> create table user(

id int(11) primary key,

name varchar(20) not null,

age int(11),

sex int(11),

index (age)) engine=InnoDB;

依然是新建一个表,创建索引,插入一些测试数据,注意这里只是为了解释说明覆盖索引,并不表示 mysql 的真实执行方式,因为会涉及到 mysql 的优化器机制,这里暂且不说了,以后再写。

1 bob 16 1

2 kom 19 0

3 gum 18 1

4 tt 20 1

5 yy 25 1

创建一个 user 表,给 age 字段添加一个二级索引,并插入上面五条数据,然后看下面这条查询语句。

select name from user where age between 18 and 21

我们来分析下这条 sql 的执行过程:

1、age 字段上有索引,mysql 会先到 age 字段的 B+ 树上找到满足条件的第一个叶子节点(age=19),这个叶子节点上保存了对应主键 id 的值 2,然后再到主键索引上找到 id 为 2 的这条记录,同时把 name 字段拿出来。

2、重复第一步的操作,继续从 age 索引上的叶子节点往后遍历找出满足条件的第二个叶子节点,同样回到主键上拿出 name 字段的值,直到遍历到不满足条件的叶子节点(age=25)。

也就是说,这条 sql 语句虽然用到了索引,但是 age 索引上并没有要查询的 name 字段,所以只能回表到主键索引上查出 name 字段,所以这个过程其实是遍历了个两个 B+ 树。

那么我们删除 age 这个单列索引,创建一个覆盖索引 (age,name), 把要查询的 name 字段也添加到索引中来。

#删除原索引

drop INDEX age on USER

#新建覆盖索引

ALTER TABLE USER add index age_name(age,name)

由于现在这个覆盖索引上的字段包含了要查询的 age 和 name 字段,免去了到主键索引上查询数据的过程,其实也就是只遍历了一个 B+ 树,可以大大提升查询效率。

添加索引虽然能提升查询效率,但索引也是需要占用额外空间的,而且索引还需要维护成本,所以通常加不加索引需要根据实际需求来权衡。

总之,在设计索引或者优化 sql 语句的时候,要尽量避免回表操作,所以使用覆盖索引是一种常用的 sql 优化手段。

所以我们平时写 sql 语句的时候,select 后面只写查询需要用到的字段,去掉不需要的字段,避免回表操作。

有问题欢迎大家留言交流,原创不易,如果文章对你有帮助,欢迎点赞,感谢支持。

MySQL 怎么变快_如何让mysql索引更快一点相关推荐

  1. python程序写完后点哪个运行快_让 Python 代码运行更快的最佳方式!

    PyPy与CPython PyPy是Python解释器CPython的直接替代品.CPython将Python编译为中间字节码然后由虚拟机解释,而PyPy使用实时(JIT)编译将Python代码转换为 ...

  2. mysql去重操作哪个最快_如何将 MySQL 去重操作优化到极致?| CSDN 博文精选

    作者 | wzy0623 责编 | 屠敏 出品 | CSDN 博客 前言 问题提出 源表t_source结构如下: item_id int, created_time datetime, modifi ...

  3. 程序调用mysql突然变慢_排查Mysql突然变慢

    定位问题 刚开始得到是系统慢的反馈,没有将问题点定位到数据库上,查了半天服务是否正常(因为之前有一次Dubbo内存泄漏). 在将应用服务日志查看了一遍后,没有发现任何异常,只是打了几个警告的日志. 于 ...

  4. 向mysql数据库发送指令_常用的MySQL数据库命令大全

    飞信2017V5.6.8860.0 官方正式版 类型:聊天其它大小:69.1M语言:中文 评分:9.6 标签: 立即下载 常用的MySQL命令大全 一.连接MySQL 格式: mysql -h主机地址 ...

  5. mysql 常规命令操作_常见的MySQL命令大全

    一.连接MySQL格式: mysql -h主机地址 -u用户名 -p用户密码1.例1:连接到本机上的MYSQL.首先在打开DOS窗口,然后进入目录 mysqlbin,再键入命令mysql -uroot ...

  6. mysql 数据库命令大全_常用的MySQL数据库命令大全

    飞信2017V5.6.8860.0 官方正式版 类型:聊天其它大小:69.1M语言:中文 评分:9.6 标签: 立即下载 常用的MySQL命令大全 一.连接MySQL 格式: mysql -h主机地址 ...

  7. mysql 分组占比_含泪整理MySQL索引

    索引优化分析 性能下降SQL慢 查询语句写的差 索引失效 单值索引 多值索引 关联查询太多join(设计缺陷或不得已的需求) 服务器调优以及各个参数设置(缓冲.线程数等) 执行时间长 等待时间长 常见 ...

  8. mysql配置好后_安装完 MySQL 后必须调整的 10 项配置

    当我们被人雇来监测MySQL性能时,人们希望我们能够检视一下MySQL配置然后给出一些提高建议.许多人在事后都非常惊讶,因为我们建议他们仅仅改动几个设置,即使是这里有好几百个配置项.这篇文章的目的在于 ...

  9. mysql 复制表耗时_聊一下mysql的表复制

    1 insert...from的问题 insert - select 是很常见的在两个表之间拷贝数据的方法.需要注意,在可重复读隔离级别下,这个语句会给 select的表里扫描到的记录和间隙加读锁. ...

  10. 解决mysql的乱码问题_完美解决mysql中文乱码的问题

    MySQL(和PHP搭配之最佳组合)中文乱码的原因 MySQL(和PHP搭配之最佳组合)会出现中文乱码的原因不外乎下列几点: MySQL(和PHP搭配之最佳组合) server本身设定问题,例如还停留 ...

最新文章

  1. 在项目管理情境下,如何做多项目管理?
  2. 键盘按下某键 停止运行java_实现按下一个键执行操作/松开一个键停止操作
  3. MySQL高级 - 锁 - InnoDB行锁 - 介绍及背景知识
  4. Hive自定义UDF UDAF UDTF
  5. 警告提示:No archetype found in remote catalog. Archetype not found in any catalog
  6. EF5.x Code First 一对多关联条件查询,Contains,Any,All
  7. Python中矩阵库Numpy基本操作
  8. object转float_人工智能-Object Detection API 模型转tflite并验证
  9. BUAA OO 2019 第一单元作业总结
  10. Linux 下载安装maven
  11. Web前端开发工具和框架
  12. 安卓模拟器安装xposed和插件
  13. 《计算机视觉黑魔法16个实战项目》之扫描全能王
  14. linux rtc与时钟
  15. Windows Style Builder一些路径分享-2022.8.21(不定期更新)
  16. Flutter开发 - 对于富文本展示的方法封装
  17. pat B1032 挖掘机技术哪家强 (20分)
  18. ecshop2.7.3+windows10(64bit)+phpstudy2018(php5.4.45+apache+mysql)
  19. 物流设计大赛 测试货物 样例 6号和23号
  20. transforms_list = [c_vision.Decode(), c_vision.Rescale(1.0 / 127.5, -1.0)]这个是图像标准化【-1,1】是吗?

热门文章

  1. C语言ftell()函数(返回文件当前位置)(返回给定流 stream 的当前文件位置)
  2. 笔记本触摸板滑动(双指滑动)太快怎么设置?
  3. python 实现队列功能 queue insert() pop()
  4. 卷积神经网络 全连接层(稠密层)是什么?(全连接层就是每一个结点都与上一层的所有结点相连的网络层)
  5. 函数式编程是啥玩意?map() reduce()(reduce()函数将数字列表转换为x进制数字)闭包、装饰器、偏函数
  6. python opencv 从Intel Realsense D435 视频流中读取并显示帧,按下空格将图像保存到指定文件夹,按下回车自动以一定时间间隔保存图像至指定文件夹
  7. PyQt4编程之自定义插槽
  8. 【Object类、日期、StringBuilder】
  9. vue教程2:vue基础
  10. keepalived 多个应用_Keepalived与LVS部署多个服务