MySQL——EXPLAIN
怎么查看一条语句是否走了索引
通过explain查看SQL的执行计划,有这些字段:
- possible_keys:可能用到的索引
- key:表示实际用到的索引,如果这一项为NULL,说明没有用到索引
- key_ken:索引的长度
- rows:表示扫描到的数据行数
- type:数据扫描类型
- extra:一些额外信息
type字段执行效率从低到高:
- ALL:全表扫描,开销很大,尽量避免
- index:全索引扫描,和all差不多,不过是对索引表进行全扫描。好处是不需要对数据进行全排序,但是仍然开销很大,因此要尽量避免
- range:索引范围扫描,一般在where子句中使用<、>、in、between等关键词,只检索给定范围的行,属于范围查找。从这一级别开始,索引的作用会越来越明显,因此尽量让type类型在这一级别及以上
- ref:非唯一索引扫描,表示采取了非唯一索引,或者唯一索引的非唯一性前缀,返回数据可能是多条,所以可能要对目标值进行小范围查询。好处是不需要扫描全表,即使有重复值,也只是在非常小的范围查询
- eq_ref: 唯一索引扫描,使用主键或者唯一索引时产生的访问方式,通常使用多表联查。比如关联条件是两张表的user_id相等,且user_id是唯一索引。
- const: 结果只有一条的主键或唯一索引扫描,表示主键或者唯一索引与常量值进行比较。比如select name from user where id = 1
extra:
- Using filesort: 查询语句包含order by语句,而且无法利用索引完成排序操作,就不得不选择排序算法来完成,甚至是文件排序,效率很低,要避免这种情况的出现。
- Using temporary:使用了临时表保存中间结果,MySQL对查询结果排序时使用临时表,常见于排序order by和group by,效率低,要避免这种情况的出现。
- Using index:数据只需在索引就可以全部获得,不需要回表,也就是覆盖索引。
extra字段中Using index和Using where的区别
- Using index:意味着SQL使用了覆盖索引,不需要回表,可以提高查询性能
- Using where:意味着MySQL服务器在存储引擎检索行后再过滤。也就是存储引擎返回的行不一定满足条件,需要在server层再过滤
如果SQL和索引都没问题,查询还是很慢怎么办
- 分批查询:将一个大的查询拆分成几个小的查询,每次查询只返回小部分数据
- 增加缓存:针对频繁查询的热点数据,可以放到Redis缓存,避免每次都要请求MySQL
- 分表:如果表的数据量比较大,经验值是500W以上,通过分表,减少每次查询的数据总量来解决查询慢的问题
- 分库:针对写多读少的问题,单库的性能无法抗住高并发,就需要分库,把并发请求分布到多个库。
- 主从复制:针对读多写少的情况,通过主从复制来分摊请求的流量