索引的过程(实际上group by也是会经历这样一个过程)
问题:select * from user where cno = 3-245;
- 如果没有索引的时候,步骤:
- 遍历整个表的内容,比较cno是否为3-245;
- 如果为3-245,就把数据放在内存的结果集中;
- 这样的话,会把表中的所有数据都查询一遍(IO多);
- 如果有索引:
- 会在cno这一列建立一个索引,把数据按照cno进行排序,并把结果变成一个倒序表;
- 查询的时候在表中查询cno为3-245的那条记录,并把结果放到结果集中;
索引的好处
- 提高检索效率;
- 如果在查询的时候,查询列==排序列(并且该列建立了索引),会大大提高排序效率;
- 如果分组的条件也是索引列的话,也会提高效率;
索引的弊端
会需要额外的成本去维护索引;因为索引文件是单独存在的,对数据的增、删、改、查都会造成索引文件额外的io。
怎样创建合适的索引?
- 较频繁的查询字段应该建立索引;
- 唯一性差的字段不适合单独作为索引字段,即使查询频繁;
解读:如果作为索引的列不能够有效的区分数据,就不适合作为索引列;例如:性别(只有两种可能性); - 更新非常频繁的字段不适合作为索引列;
- 索引不是越多越好;
- 不管有多少个索引,一次查询只会使用一个索引(mysql引入复合索引);
- 每个索引之间都是都是独立,数据的增、删、改、查都会造成每个索引文件的单独维护;
索引的使用限制
- Blob和Text只能创建前缀索引;
- mysql目前不支持函数索引(索引值是原始的值(birthday),函数作用(year(birthday)后无效);
- 在mysql中,使用了!= <>不能使用索引;
- 使用like匹配时:
- 字符串是可以用来作为索引的,按照字母顺序排序;
- ‘h_’ 、 ‘h%’ 是可以使用索引的;
- ‘_h’ 、’%h’不可以使用索引;
复合索引
概念:就是多列的值组合成的索引,并且,多列的索引是有序的;原理:类似order by(order by age,name)。例如:
select from user where age < 30 ; 可以使用age+height的复合索引;
select from user where age < 30 and height <170; 可以使用age+height的复合索引;
select from user where height <170; 不能使用age+height的复合索引;
select from user where height <170 and age < 30; 不能使用age+height的复合索引(但是mysql会优化,交换两者位置);复合索引在查询的时候,遵循向左原则,只要是在查询过程中,是从左向右的执行,不管查询条件是否完全满足复合索引的列,都可以使用部分的复合索引;例如:
现有复合索引:ABCD;如果where后面条件为:- AB –> 可以使用;
- 2)AC –> 可以使用(只是使用A);
- 3)BC –> 不可以;
- 实际开发中,基本都使用复合索引;