通常大家都会根据查询的where条件来创建合适的索引,不过这只是索引优化的一个方面.设计优秀的索引应该考虑到整个查询,而不单单是where条件部分.索引确实是一种查询数据的高效方式.但是mysql也可以使用索引来直接获取列的数据,这样就不再需要读取数据行.如果索引的叶子节点中已经包含要查询的数据,那么还有什么必要再回表查询呢?
如果一个索引包含(或者覆盖)所有需要查询的字段的值,我们就称为"覆盖索引"
覆盖索引是非常有用的工具,能够极大的提高性能,考虑下如果查询只需要扫描索引而无需回表,会带来多少好处:
* 索引条目通常远小于数据行大小,所以如果只需要读取索引,那mysql就会极大地减少数据访问量.这对缓存的负载非常重要,因为这种情况下响应时间大部分花费在数据拷贝上.覆盖索引对于IO密集型的应用也有帮助,因为索引比数据更小,更容易放到内存中(对于myisam,他能压缩索引)
* 因为索引是按照列值顺序存储的(至少在单个页内是如此).所以对于IO密集型的范围查询会比随机从磁盘读取每一行数据的IO要少的多.对于某些存储引擎,例如myisam和XtraDB,甚至可以用OPTIMIZE命令使得索引完全顺序排列,这让简单的范围查询能使用完全顺序的索引访问
* 一些存储引擎如myisam在内存中只缓存索引,数据则依赖于操作系统来缓存,因为要访问数据需要一次系统调用.这可能会导致严重的性能问题,尤其是那些系统调用占了数据访问中的最大开销场景
* 由于Innodb的聚簇索引,覆盖索引对Innodb表特别有用,Innodb的二级索引在叶子节点中保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询
在这些场景中,在索引中满足查询的成本一般比查询行要小很多
不是所有类型的索引都可以成为覆盖索引.覆盖索引必须要存储索引列的值,而哈希索引,空间索引和全文索引等都不存储索引列的值,所以mysql只能使用B-Tree索引做覆盖索引.另外,不同的存储引擎实现覆盖索引的方式也不同,而且不是所有的引擎都支持覆盖索引
当发起一个被索引覆盖的查询(也叫索引覆盖查询),在explain的extra列可以看到Using index的信息.例如:表sakila.inventory有一个多列索引(store_id,film_id).mysql如果只需访问这两列,就可以使用这个索引做覆盖索引
![](https://box.kancloud.cn/13e5e797c5d98ac27915e411cef76e02_541x253.png)
(很容易把extra列的Using index和type列的index搞混淆.其实这两者完全不同,type列和覆盖索引毫无关系,它只是表示这个查询访问数据的方式,或者说mysql查找行的方式)
索引覆盖还有很多陷阱可能会导致无法实现优化.mysql查询优化器会在执行查询钱判断是否有一个索引能进行覆盖
假设索引覆盖了where条件中的字段,但不是整个查询涉及的字段.如果条件为假,mysql5.5和更早的版本也总是会回表获取数据行,尽管并不需要这一行且最终会被过滤掉
- 书列表
- laravel框架关键技术
- 第一章 组件化开发与composer使用
- 简介
- composer
- 添加路由组件
- 添加控制器模块
- 添加模型组件
- 添加视图组件
- 第三章 laravel框架中常用的php语法
- 匿名函数
- 文件包含
- 魔术方法
- 魔术常量
- 反射
- 后期静态绑定
- traits
- 第四章 laravel框架中使用的HTTP协议基础
- HTTP协议
- 数据库
- 数据迁移
- 第六章 laravel框架中的设计模式
- IOC模式
- php核心技术与最佳实践
- 第一章面向对象核心
- 反射
- 简单ORM
- 异常和错误
- 接口
- 第二章,面向对象设计
- 设计原则
- 单一职责
- 接口隔离
- 开放封闭
- 替换原则
- 依赖倒置
- linux是怎么写的呢?
- 第三章 正则表达
- 认识正则
- 第四章 php网络技术应用
- HTTP协议详解
- php和http相关函数
- 垃圾信息防御措施
- 现代操作系统
- 引论
- sql必知必会
- 限制结果
- 按位置排序
- where求职顺序
- IN操作符
- like
- 函数
- group by
- 组合查询
- 插入检索出的数据
- 视图
- 高性能mysql
- 第一章节 mysql架构与历史
- mysql架构逻辑图
- 连接与管理
- 优化与运行
- 读写锁
- 锁粒度
- 表锁(table lock)
- 行级锁(row lock)
- ACID
- 隔离级别
- 死锁
- 隐式和显式锁定
- 多版本并发控制
- Innodb概览
- 第四章节 Schema与数据类型优化
- 选择优化的数据类型
- 日期和时间类型
- 标识列
- 特殊类型数据
- 表设计中的缺陷
- 范式
- 计数器表
- 第五章 创建高性能索引
- 索引基础
- 索引类型
- 索引的优点
- 高性能索引策略
- 选择合适的索引列顺序
- 聚簇索引
- 顺序的主键什么时候会造成更坏的后果
- 覆盖索引
- 使用索引扫描来做排序
- 压缩索引
- 冗余和重复索引
- 索引和锁
- 支持多种过滤条件
- 什么是范围条件
- 优化排序
- 维护索引和表
- 表损坏
- 减少索引和数据的碎片
- 第六章 查询性能优化
- 扫描的行数和访问类型
- 重构查询方式
- 查询执行的基础
- 重构-改善既有代码设计
- 第一章-重构
- 什么是重构
- 第一个案列
- 重构第一步
- 王垠博客
- 多态取代价格相关逻辑