一、认识索引
索引优化,是mysql数据库优化的最常用的手段之一,索引为什么可以加快query的执行速度呢
mysql中,主要有四种索引:B-tree索引,Hash索引,Fulltext索引和R-tree索引
索引功能:
1、保持数据完整性
2、优化数据访问性能
3、改进表的连接(join)操作
4、对结构进行排序
5、简化聚合数据操作
innodb存储引擎中,存在两种不同形式的索引,一种是cluster形式的主键索引,一种是和其他存储引擎存放形式基本相同的普通B-tree索引,这种索引在innodb中称之为secondary index(二级索引)
二者的区别:主键索引存储的是page页地址,而二级索引存储的是对应的主键id,在结构上没有太大的区别
所以在innodb中使用主键来访问,效率非常高,如果通过二级索引来访问,首先需要根据二级btree获取id,再根据id查询数据(这个过程也就是回表)

二、索引的利弊以及建立的一些规则
好处:可以提高对于数据的查询效率,降低数据库的IO层,同时也提高排序和分组对于CPU资源的消耗
坏处:当创建一个索引后,比如table创建一个idx_city的索引,这个时候,当数据表table内容一旦发生变化之后,mysql就会重新调整索引结构,如果数据表的字段是一些字符串类型的,可能调整的会稍微久一点,并且是每一个索引都会相应的调整

挑选索引—建立的一些规则
1、索引应该建立在搜索、排序、归组等操作涉及的数据列上,只在输出报告里面出现的字段不是好的选择。也就是说,那些在where字句、关联检索中的from字句、order by 或group by字句中出现的字段适合用来创建索引,只在select关键字后面的字段不是好的选择
2、尽量使用唯一索引。数据值在数据列中的分布情况是一个很值得考虑的因素。建立在唯一字段(字段值都不相同)上的索引着更好的效果。如果字段的值有很多彼此重复的值,建立在上面的索引就不会有很好的效果。比如说:某个字段存放着不同的年龄值,建立在其上的索引就能把不同的数据行很好的区分开来。如果某个字段里存放的是用来表示性别的1和0两种值,建立在其上面的索引恐怕就不能有很好的效果。如果数据值分布的比较均匀,那边不管用那个值(0或1)进行搜索都能匹配大运50%(甚至30%)的数据行。在这种情况下,mysql根本就不糊使用建立在这个字段上的索引----当查询优化器发现某个数据值在超过30%的数据行里都有出现的时候,他通常会放弃使用相关的索引而进行一次全表扫描

PS:这里并不是说性别就不能创建索引,而是指不适合单独建立索引,我们可以创建一个唯一的包含性别的唯一索引,比如:select count(*),avg(monthsalary) from customer where gender = 0;可以创建一个idx_gender_monthsalary的索引

alter table customer add index idx_gender_monthsalary(gender,monthsalary);

mysql索引命中失败的情况:
1、where条件后面有or

select * from user where id = 1 or age = 18;


如果想要or后面的也走索引的话,就需要给两个字段都建立索引
2、like以“%”开头的不会命中索引

select * from user where username like ‘%张%’;


3、如果字段类型为字符串,一定要将数据值用引号包起来,否则不会使用索引

select * from user where mobile= 17837802994;//不使用索引
 selec * from user where mobile=‘17837802994’;//使用索引


4、没有查询条件或者查询条件没有建立索引
5、使用not in , not exist,无法命中索引
6、B-tree 索引 is null不走索引,is not null走索引