为什么要使用联合索引

  • 减少开销

建一个联合索引(Gid,Cid,SId),实际相当于建了(Gid)、(Gid,Cid)、(Gid,Cid,SId)三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销。

  • 覆盖索引

对联合索引(Gid,Cid,SId),如果有如下的sql: select Gid,Cid,SId from student where Gid=1 and Cid=2。那么MySQL可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io操作。减少io操作,特别的随机io其实是dba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。

  • 效率高

索引列越多,通过索引筛选出的数据越少。有1000W条数据的表,有如下sql:select from table where Gid=1 and Cid=2 and SId=3,假设假设每个条件可以筛选出10%的数据,如果只有单值索引,那么通过该索引能筛选出1000W10%=100w条数据,然后再回表从100w条数据中找到符合Gid=2 and Cid= 3的数据,然后再排序,再分页;如果是联合索引,通过索引筛选出1000w10% 10% *10%=1w,效率提升可想而知!

  • 缺点

联合索引越多,索引列越多,则创建的索引越多,索引都是存储在磁盘里的,通过索引算法(Btree代表索引算法使用二叉树的形式来做索引的)来查找数据,的确可以极大的提高查询效率,但是与此同时增删改的同时,需要更新索引,同样是需要花时间的,并且索引所占的磁盘空间也不小。

前提:MySQL InnoDB存储引擎

案例分析:创建一张用户表




联合索引 范围查询 联合索引什么时候失效_联合索引 范围查询

表中没有创建任何索引



创建复合索引

创建命令:create index user_nameAgePos

创建顺序:name、age、pos




联合索引 范围查询 联合索引什么时候失效_联合索引_02


我们从上图可以看出,复合索引user_nameAgePos中name排第一、age排第二、pos排第三

下面这三种情况都会用到索引:


联合索引 范围查询 联合索引什么时候失效_mysql 时间索引失效_03


结论:

  • 在复合索引中,全值匹配才是最高效的索引使用法则(就是安照创建索引的顺利在实际中完全匹配使用)。
  • 在复合索引中,要想索引不失效,排第一的索引不能少

索引失效案例分析:


联合索引 范围查询 联合索引什么时候失效_联合索引 范围查询_04


测试一:复合索引使用过程中,当我们使用排名第二或第三、或者使用第二和第三的索引时,都会导致全表扫描,导致索引失效。

结论:

  1. 复合索引中的带头大哥若没有使用,则直接会导致索引失效。
  2. 如果带头大哥索引和排序第三以后的所有使用了,但中间索引没有用,其实只是部分用到索引,且只使用到了带头大哥索引