文章目录
一、MySQL中索引一定有效吗?如何排查索引的效果?
- 不一定有效,不一定会用到索引,使用索引不一定不全表查询快
- MySQL最终是否走索引,靠的是优化器的最终计算,优化器会计算走索引和全表扫描各自的IO成本和CPU成本,哪个成本低就选哪个。
- 排查索引用
explain+查询语句 ,重点看下面的几个字段type、row、key、extra.- type:
ALL表示全表扫描、index表示全索引扫描、range表示范围扫描、ref表示等值扫描 - rows: 预估扫描行数,行数越大说明成本越高
- key: 实际使用的索引名,null表示没有用到索引(全表扫描)
- extra:
using index表示使用联合索引,不用回表、using index condition表示经过了回表
- type:
二、索引失效的场景
索引失效是面试高频考点,场景不少,但背后的原因基本就两类:一是查询条件导致索引树的快速查找能力用不上,二是优化器算了一笔账觉得不划算。
- 违反最左匹配原则
- 索引列上做了运算
- 索引列上使用了函数
- like左侧带%号的模糊查询
- 用or关键字关联非索引字段
where name = 'lyq' or age = 20, 如果age没有索引,MySQL没有办法通过索引快速过滤age条件,整个查询可能退化成全表查询。
- 隐式的类型转换
- name是varcher类型,查询写成了
where name = 1
- name是varcher类型,查询写成了
- 优化器认为全表扫描更划算
- 同一个索引,热点数据可能会走全表扫描,而冷门数据会走索引,因为,热点数据多,走索引会产生大量的回表操作,不如全表扫描
group by后的字段没有索引
三、什么是索引下推?
索引下推是MySQL5.6引入的优化技术,目的是减少回表次数,提升查询效率。
核心思路是把部分条件过滤下推到引擎层,在引擎层就把不符合的数据过滤掉,不用再回表查询所有数据。
- 以前的流程是:引擎层通过索引定位数据,返回主键给Server层,Server层回表拿去所有数据,再通过剩下的条件过滤数据。
- 有了索引下推,引擎层就能直接通过索引里的列过滤不符合的数据,不符合的数据就不需要回表操作。
- 索引下推主要用在联合索引中
四、建索引时的注意事项
索引不是越多越好,每个索引都占磁盘空间,每次写入都要维护索引的B+树,索引越多插入效率越低。
- 区分度太低的字段不要建立索引,比如说性别,就两个值,建了索引也没什么过滤效果,不过也有例外,比如说定时任务表,大部分都是成功,只有少量失败,通过失败状态查询能过滤掉大量的数据,这时候的建索引就是有意义的。
- 大字段不要建立索引。
- 写多读少的字段不要建立索引。
- 频繁查询的字段要建立索引
distinct、group by、order by后面的字段要建立索引。
五、联合索引的设计原则
- 区分度高的放前面
- 查询效率高的放前面
- 范围查询的放后面
- 利用覆盖查询
六、联合索引和多个单例索引的区别
联合索引是一颗B+树,多个单例索引是多个B+树,查询时,单例索引通常只能走一个索引,而联合索引能同时利用多个列过滤。