在正文之前首先讲一下mysql构建索引树(B+)时的特性,例如创建(a,b,c)一个联合索引,则mysql会以a字段的顺序来构建B+数,然后a如果相同,则b字段再排序,依此类推。
所以查询条件中如果不包含a列的话,一般都是不会命中索引的。因为无论是b列还是c列,相对来说都是一个无序的,只是在a列相同的情况下,b列小范围的有序;
select * from my_test where a='' and b='' and c='';命中索引
select * from my_test where a='' and b='';命中索引
select * from my_test where a='' and c='';命中一列索引
select * from my_test where a='';命中索引
select * from my_test where b='' and c='';不会命中索引
select * from my_test where b='';不会命中索引
select * from my_test where c='';不会命中索引
首先创建表结构和联合索引:
1.如果对a(字符型字段)字段进行模糊查询:
select r.* from my_test r where r.a like '21%' ; (命中索引)
select r.* from my_test r where r.a like '%1%' ;(未命中索引,全表扫描)
select r.* from my_test r where r.a like '%1' ;(未命中索引,全表扫描)
总结:在联合索引的情况下(a,b,c),对a(carchar)字段进行模糊查询,只要%放在开头都不会命中索引,因为数据库在检索时,是以联合索引的第一个列开始检索,字符型的话,是以首字母开始比较检索,如果首字母相同则检索第二个字符,依此类推;
2、再来实验范围查询:
将a字段的类型改成int类型
select r.* from my_test r where r.a >10 ;(命中索引)
select r.* from my_test r where r.a >10 and r.b>1; (命中索引,只有a列用到了索引,b未用到索引,因为b列在a>10这个范围内是无序的,无法用到索引。)
select r.* from my_test r where r.a =210 and r.b>1;(命中索引,因为在a=210的情况下,b是有序的,所以是走的联合索引)