当前位置: 首页 > news >正文

覆盖索引有何用?

通常开发人员会根据查询的where条件来创建合适的索引,但是优秀的索引设计应该考虑到整个查询。其实mysql可以使用索引来直接获取列的数据。如果索引的叶子节点包含了要查询的数据,那么就不用回表查询了,也就是说这种索引包含(亦称覆盖)所有需要查询的字段的值,我们称这种索引为覆盖索引。

注:引入数据表t_user,插入约1千万条记录,用作下文例子使用。

1工欲善其事,必先利其器

        explain命令是查看查询优化器如何决定执行查询的主要方法。要使用此命令,只需要在select关键字之前添加这个命令即可。当执行查询时,它会返回信息,显示出执行计划中的每一部分和执行的次序,而并非真正执行这个查询。如图1.1所示,是执行explain的显示结果,其中sql语句中的\G表示将输出按列显示:

图1.1 explain显示查询执行计划

    当发起一个被索引覆盖的查询时,在explain的Extra列可以看到 Using index的标识。

 

2场景:查询表中name列有值的记录数

图2.1 查询name列有值的记录数

 

图2.2 执行计划

       如上图2.1所示,其中查询语句用SQL_NO_CACHE关键字来禁止缓存查询结果。此查询耗时6.43秒。从图3的执行计划得知,type:ALL,表示MySQL扫描整张表,从头到尾去找到需要的行。下面对此查询列建立索引。

图2.3 为name列建立索引

 

图2.4 重新执行的查询sql

图2.5 重新查看执行计划

    如图2.3所示,为name列建立索引之后,重新执行查询。此时查询耗时3.80秒,比未加索引提高了2.63秒。从图2.5的查询计划可知,type:index,这个跟全表扫描一样,只是MySQL扫描表时按索引次序进行而不是行。但是看到Extra:Using index,说明MySQL正在使用覆盖索引,它只扫描索引的数据,而不是按索引次序的每一行。它比按索引次序全表扫描的开销少很多。

3分页查询email

图3.1 分页查询email

图3.2 分页查询执行计划

    从图3.1可知,分页查询耗时53.99,如图3.2所示,type:All,说明MySQL进行了全表扫描。下面在password和email列上创建联合索引。

图3.3 添加联合索引

图3.4 重新分页查询

图3.5 重新执行查询计划

如图3.4所示,分页查询基本不耗时间。从图3.5可知,Extra:Using index,MySQL使用了覆盖索引进行查询。查询效率得到极大的提升。

4覆盖索引总结

回想一下,如果查询只需要扫描索引而无须回表,将带来诸多好处。

(1)索引条目通常远小于数据行大小,如果只读取索引,MySQL就会极大地减少数据访问量。

(2)索引按照列值顺序存储,对于I/O密集的范围查询会比随机从磁盘中读取每一行数据的I/O要少很多。

(3)InnoDB的辅助索引(亦称二级索引)在叶子节点中保存了行的主键值,如果二级索引能够覆盖查询,则可不必对主键索引进行二次查询了。

    覆盖索引就是从索引中直接获取查询结果,要使用覆盖索引需要注意select查询列中包含在索引列中;where条件包含索引列或者复合索引的前导列;查询结果的字段长度尽可能少。

相关文章:

  • Mysql性能优化、Mysql参数优化、Mysql配置优化
  • 搭建git服务器仓库
  • git如何恢复已经push的内容
  • php连接mysql报错:SQLSTATE[HY000] [2002] No such file or directory
  • MySQL分页优化
  • PHP使用CURL详解
  • 从输入URL到页面加载完成都在哪些层经过了哪些步骤?
  • 利用PHP访问带有密码的Redis
  • linux下安装redis服务和php扩展
  • 搭建lnmp环境,看完傻瓜都会
  • Linux定时任务执行PHP脚本每天更改数据库
  • js实现手机web页面定位
  • OpenCC for PHP 简繁体转换
  • php安装zip
  • Nginx配置优化
  • 分享一款快速APP功能测试工具
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 2017年终总结、随想
  • CSS 专业技巧
  • jquery cookie
  • js 实现textarea输入字数提示
  • Puppeteer:浏览器控制器
  • Python_网络编程
  • Rancher-k8s加速安装文档
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • SpiderData 2019年2月25日 DApp数据排行榜
  • 安卓应用性能调试和优化经验分享
  • 分布式事物理论与实践
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 记录一下第一次使用npm
  • 前端js -- this指向总结。
  • 浅谈Golang中select的用法
  • 深入浏览器事件循环的本质
  • 网页视频流m3u8/ts视频下载
  • 栈实现走出迷宫(C++)
  • 大数据全解:定义、价值及挑战
  • 通过调用文摘列表API获取文摘
  • ​如何在iOS手机上查看应用日志
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • (1) caustics\
  • (Java)【深基9.例1】选举学生会
  • (NSDate) 时间 (time )比较
  • (补)B+树一些思想
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (十一)图像的罗伯特梯度锐化
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)视频码率,帧率和分辨率的联系与区别
  • (轉)JSON.stringify 语法实例讲解
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .gitignore文件_Git:.gitignore
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .NET CF命令行调试器MDbg入门(三) 进程控制