1.为什么索引可以加快数据库的检索速度?
MySQL的基本的存储结构是页,行存储在页的User Record区域,各个数据页可以组成一个双向链表,而每个数据页中的行记录又可以组成一个单向链表。
select * from coupon_detail where user_id = "1231312313";
如果user_id不是索引字段,那么MySQL会先遍历双向页链表,找到数据所在的页,再遍历页的单向链表,找到user_id为1231312313的数据行;
如果user_id是索引字段,那可以利用B+树(主流索引结构,时间复杂度O(lgn))快速找到数据所在的页,再在页中快速找到对应的数据行,这就是索引的查询速度很快的原因。
2.为什么索引会降低插入、删除、修改的速度?
由于主流索引是B+树,而B+树是一种平衡树,如果对树进行增删改的话,会破坏树的结构,要维持树的平衡,必须做左旋/右旋来使B+树重新处于平衡状态,这些平衡开销会降低索引处理增删改任务的速度。
3.什么是B+树索引?什么是Hash索引?主流的索引是什么?InnoDB都支持什么索引?
B+树索引只有叶子节点存储的是数据,其他节点存储的都是下一次节点的索引。
Hash索引就是讲键值转换成哈希值,查询时,只需要哈希算法就可定位数据的位置。
主流的索引的B+树索引,因为哈希索引不支持范围查询;主键值重复时,会发生碰撞;不支持最左侧匹配,没法利用哈希索引排序,即使用order by对结果排序。
InnoDB同时支持B+树索引和Hash索引。
4.什么是索引的最左侧匹配原则?
最左侧匹配是针对联合索引的,在多个key组成的联合索引中,索引只能用于查找key是否存在(相等),遇到范围查询(>、<、 between 、like)就不能进一步匹配了,后续的查询退化为遍历链表。
例如有联合索引(user_id,user_level ,use_status)
select * from coupon_detail where user_id = "1231312313" and user_level > 3 and use_status = 1;
这次查询会命中user_id和use_status,但是user_level使用的是范围查询,联合索引匹配到user_level 就结束了,后续的use_status = 1就只能遍历数据页的链表了。