联合索引-以及如何使用索引

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了联合索引-以及如何使用索引相关的知识,希望对你有一定的参考价值。

参考技术A 建立索引的时候,尽量建立联合索引,即多个字段组成1个索引。因为如果针对单个字段建立索引的话,会造成索引过多,每次插入数据都会维护多个索引,导致数据加入性能过慢。索引条目里面一定会带一个id,区分大小的唯一主键。

聚合索引就是根据多个字段建立起来的索引,索引树的最底层的数据页保存的是索引字段+主键字段。如果字段值一样的话,就按照下一个字段排序。例如,建立一个persion表, 有字段 id,name, age , height ,weight,phone 。
然后用age ,height 建立联合索引,如下图:

这时候,添加一个age=18,height=177的用户的添加过程是去到索引页1,发现age >15并且age <20 ,所以这条记录会添加到数据页1。 然后去数据页1根据age进行二分查找,发现age>最后一条数据(id=4),这时候就将需要添加的数据,加到最后一条后面。

如果再添加一条数据age=21 ,height=167。 首先去到索引页1用age进行二分查找,发现应该添加到数据页2。然后去数据页2进行二分查找,发现age=21和id=6,id=7的数据age一样。 然后就看第二个字段height=167,比id=6的166大,比id=7的170小,所以就添加到id=6 和 id=7的数据中间。

如果遇到字段都一样的,就根据ID的大小来排序。

在where子句里面的字段,条件都是用“=”等号,字段和也索引里面的字段一致,顺序不一致也没关系,SQL优化会自动进行重新排序。这时候就可以100%使用索引进行查询。

例如上面的例子,如果查询的时候,是使用age = xx 查询,那么就可以用上索引。如果跳过age,使用height=XX来查询,那么是没办法使用到索引的,因为索引的排序是根据建立索引的字段顺序来排序的。

查询的时候,如果使用了like类型的模糊匹配, like%,这样的写法是可以用索引的,当然要符合最左列匹配规则。 如果是%like 这样的写法,是无法使用索引的,因为无法确认字段的开始字符串是什么,所以就无法用来和索引进行对比。

如果使用了范围查找,使用索引的最左列字段来查找是可以使用索引查找的。因为索引的每一层和数据页都是通过双向量表连接起来的。 例如age > 15 and age < 21,那么就可以定位到数据页1,id=1的数据和数据页2,id=5的数据,然后取个范围内的数据就可以了。

但是如果用的是height来做范围查找就用不了索引: height >170 and height <180。 这时候数据页1 和数据页2 都是存在符合条件的数据的,但是,数据页内,没有按照height来排序,所以,需要遍历才能找到,然后数据页2也需要遍历才能找到。

第一个条件是使用了=来匹配,如果这个条件的字段是索引的第一个字段,那么是会走索引的, 然后第二个条件,如果是按照范围来查找, 如果这个字段是索引的第二个字段,那么也可以用到索引, 再来第三个条件, 如果是=号匹配,这个条件也是索引的第三个字段的话,就可以用索引,如果是用范围匹配, 那么是用不了索引的。 原因是,索引用第二个字段进行了排序, 然后第三个字段是在第二个字段相同的情况下,再进行排序。

记住一个原则就是, 索引有3个字段, 先用第一个字段进行排序, 如果第一个字段一样,就用第二个字段排序, 如果第二个字段的值也一样, 那么就用第三个字段排序。 根据这个排序的规则,去匹配查询的条件,即可知道这5个索引的匹配规则。

排序的时候也符合索引使用规则, 使用索引的字段进行排序的话,就可以直接从索引里面,直接获取数据即可。 用上面的例子,如果有SQL :

本身索引就是按照age和height来排序的,所以直接可以在索引里面找到对应的数据,然后取前面2条返回。 升序和降序都没关系,都可以找到一个连续确定的范围。索引默认是从小到大排序。

如果排序是order by age desc height asc,那就不会使用到索引,因为索引也是按照从小到大排序的,遇到第一个字段相同值的,就按照第二个字段从小到大排序。

使用grouop by的时候,也是注意使用索引最左列来分组, 这样,就可以按照顺序,重一定的范围内提取出整个分组数据,然后再对这个分组数据进行操作。 就不需要从无序的数据里面,重新进行排序再提取,这样就会涉及到很多硬盘交互操作。

以上是关于联合索引-以及如何使用索引的主要内容,如果未能解决你的问题,请参考以下文章

联合索引

如何给mysql表建立联合索引

联合索引覆盖索引及最左匹配原则|MySQL索引学习

Mysql联合索引的最左前缀原则以及b+tree

MySQL中的联合索引覆盖索引及最左匹配原则

16-索引