一、不满足最左前缀
当我们给一个表的几个字段创建联合索引的时候,我们查询的时候要满足最左前缀原则,否则索引会失效或者部分失效。
因为索引树的建立本质上也是一个比较排序的过程,而联合索引建树,几个字段也是有权重的,例如有一张Student表,给它的age phone email建立联合索引,那么比较规则就是age大就大,age相同比较phone,phone相同比较email。最左前缀就是查询条件必须有第一个字段,其他条件不能间断
比如
select * from student where age=xx and phone='xx' and email='xx' 使用了完整的索引(可以通过explain 解释sql执行过程)
select * from student where age=xx and phone='xx' 也使用了完成的索引
select * from student where age=xx and email='xx' 使用的就是部分的索引(可以理解为索引的效率没达到最高,因为联合索引在这里只针对age是有序的,而不是针对age和email是有序的)
select * from student where phone=xx and email='xx' 完全没有使用索引(联合索引针对phone和email是无序的)
二、在索引列上使用函数操作
例如
select * from student where substring(age,0,1)='1',因为像这种函数操作,不执行函数前怎么知道这个数据是否符合条件,所以需要对所有行执行这个函数操作,不会使用索引
三、字符类型不加单引号
例如(phone是字符类型)
select * from student where phone = '1234'
select * from student where phone = 1234
上面的那个会使用索引,下面不会
四、头部模糊查询
explain select * from student where name like 'a%' (索引不会失效)
explain select * from student where name like '_a'(索引失效)
五、使用or
select * from student where name='xx' or age=xx,需要name和age都建立了索引,其中一个没有索引也会失效,因为其中一个没有就需要全表扫描了,另外一个索引也没有意义了
六、数据本身
如果某个查询,数据库觉得走索引不如不走,那么数据库就不会走索引
select * from user where phone is null(如果空数据少就会走,反之不走)
select * from user where phone is not null(如果空数据多就会走,反之不走)