MySQL索引常见问题

目录

      • 问题1:用联合索引优化using filesort
      • 问题2: 给区分度高的字段加索引
      • 问题3:select字段会导致回表
      • 问题4:多个字段有索引,使用哪个索引?
      • 问题5:内连接之大表小表
      • 问题6:模糊搜索使用索引
      • 问题7:in和not in是否用到索引?not in优化成range范围搜索
      • 问题8:索引字段涉及函数以及类型转换,无法用到索引
      • 问题9:or不能使用索引

问题1:用联合索引优化using filesort

MySQL索引常见问题_第1张图片
首先最基本的userId这个字段肯定要加索引,因为我们一般都是用过滤条件来加索引的,和 select选择什么列加不加索引没关系。如果仅仅给userId加索引的话,创建的是二级索引树,叶子节点放的是二级索引和它所在的那一行的主键值,现在是select *肯定还要涉及一次回表,更重要的是还order by addtime了,如果addtime没有建索引的话,这个语句用explain分析后在extra会出现using filesort,因为涉及了addtime的排序,是耗费性能的,遇见using filesort一定要把它优化掉,所以我们应该创建联合索引,用userId和addtime共同来创建索引,先通过userId进行排序,在userId相同的情况下再通过addtime进行排序,这样当userId选好以后,选出来的结果的addtime在这个二级索引树上就已经排好序了,就没有using filesort。

MySQL索引常见问题_第2张图片
在这里插入图片描述

对于其他自己建的索引,一般叫辅助索引,那么辅助索引的树,叶子节点存了两样东西:二级索引和它所在的那一行的主键值。当有where条件,比如where addtime=‘今天’,MySQL直接从addtime索引,先找到符合条件的addtime,再从叶子节点中取出主键值,跑去主键的那个树,取回整行数据。也就是先搜索二级索引树,再搜索主键索引树。
MySQL索引常见问题_第3张图片
是有差别的,addtime没有建索引的话,有using filesort要做数据的外排序,用userId选择出来的数据量越多,耗费的排序性能差的越大。
MySQL索引常见问题_第4张图片
addtime有索引,那平衡树上的数据就是按addtime排好序了。

问题2: 给区分度高的字段加索引

MySQL索引常见问题_第5张图片

给字段加了索引最终还要用这个字段加过滤条件或者排序,是不是索引就一定能用到?实际上MySQL Server在分析优化sql语句的时候,会分析判断要不要使用索引以及用哪个索引,如果它发现用索引扫描的数据量和整表扫描差别不大,实际上就不走索引了,因为走索引费的事比较多。

举例:

MySQL索引常见问题_第6张图片
MySQL索引常见问题_第7张图片
因为用索引过滤出来的数据量已经占到整表搜索的百分之五十了,效率提升没有那么明显,就没有必要了,还不如做整表搜索。

问题3:select字段会导致回表

在这里插入图片描述
如果不需要那么多的字段,就不要select太多,这会导致回表,影响效率。能直接在二级索引树上取的就直接取,避免回表!

问题4:多个字段有索引,使用哪个索引?

MySQL索引常见问题_第8张图片
一张表的一次查询只能用到一个索引。用哪个索引过滤出来的数据量少选择哪个索引
MySQL索引常见问题_第9张图片
MySQL索引常见问题_第10张图片
MySQL索引常见问题_第11张图片
MySQL索引常见问题_第12张图片
可以强制指定使用某个索引select * from xxx force index(IX_addtime),这样不管怎样都走到addtime索引上。
MySQL索引常见问题_第13张图片

问题5:内连接之大表小表

MySQL索引常见问题_第14张图片
MySQL索引常见问题_第15张图片
内连接的时候,小表是整表扫描,每一个都要用到,大表相关联的字段没有索引的话,小表的每一个uid在大表中搜索都是整表搜索。如果大表相关联的字段有索引,小表的每一个uid在大表中就是走索引,搜的非常快。

确定大表还是小表:先用where进行数据过滤,谁的数据少谁就是小表

小表决定循环次数,大表决定每次循环的查询时间。

问题6:模糊搜索使用索引

MySQL索引常见问题_第16张图片
like通配符放在最前,还有这几种运算符,都无法用到索引。
MySQL索引常见问题_第17张图片
第一个zhang%通配符在后面,可以利用索引进行前缀搜索,可以根据前缀的匹配缩小搜索范围。对于字符串类型来说,索引长度(key_len)不需要很长,只需要能区分每个字符串数据即可,索引过长,导致索引文件变大,创建索引树的时候花费的磁盘I/O也就多了

第二个%zhang%通配符在前面,可以匹配任意的数据,所以只能整张表搜索

问题7:in和not in是否用到索引?not in优化成range范围搜索

MySQL索引常见问题_第18张图片

MySQL做的优化:not in可以转化为range搜索查询

问题8:索引字段涉及函数以及类型转换,无法用到索引

MySQL索引常见问题_第19张图片
本来是按照password排序作为索引的,经过函数计算之后就成为了另外的值,所以无法使用索引
MySQL索引常见问题_第20张图片
索引字段涉及类型强转、mysql聚合函数调用、表达式计算等,不会使用索引

问题9:or不能使用索引

or 实际上也可以用到索引,MySQL会对or进行优化成union联合查询

MySQL索引常见问题_第21张图片
优化成union后的两个select应该是都可以使用索引的,究竟用不用,还得看使用索引是否能带来效率的提升
MySQL索引常见问题_第22张图片
总结:
MySQL索引常见问题_第23张图片

当被问到SQL和索引优化问题是,怎么切入?
要看从哪些地方能够获取哪些运行时间长,耗性能的sql;然后再用explain去分析相应的sql,就可以知道索引有没有用,或者是没有建索引需要加索引(主键、unique还是二级索引),再看有没有分组排序,如果有where又有分组排序,要考虑加联合索引。

你可能感兴趣的:(数据库,mysql,b树,数据库)