基本存储结构是页
每个数据页可以组成一个双向列表
每个数据页中的记录又可以组成一个单向列表
- 每个数据页都会为存储在它里边儿的记录生成一个页目录,在通过主键查找某条记录的时候可以在页目录使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。(???)
- 以其他列(非主键)作为搜索条件:只能从最小记录开始依次遍历单链表中的每条记录 所以说,如果我们写select * from user where indexname = 'xxx’这样没有进行任何优化的sql语句,默认会这样做:
1.定位到记录所在的页:需要遍历双向链表,找到所在的页
2.从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了,很明显,在数据量很大的情况下这样查找会很慢!这样的时间复杂度为O(n)。
很明显的是:没有用索引我们是需要遍历双向链表来定位对应的页,现在通过目录可以很快地定位到对应的页上了!(二分查找,时间复杂度近似为O(logn))。
其实底层结构就是B+树,B+树作为树的一种实现,能够让我们很快地查找出对应的记录。
总结:存储的数据都是放在页中。
- 没有索引时,页的底层结构时链表+双向链表,只能一条一条地去查询
- 而使用索引之后,页的底层结构就是B+树了,大大加快了数据的查询速度
索引遵循的原则
最左前缀原则
MySQL中的索引可以以一定顺序引用多列,这种索引叫作联合索引。如User表的name和city加联合索引就是(name,city),而最左前缀原则指的是,如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以被用到。如下:
select * from user where name=xx and city=xx ; //可以命中索引
select * from user where name=xx ; // 可以命中索引
select * from user where city=xx; // 无法命中索引
因为索引只能从左边开始匹配,而不能直接跳到右边,使用右边的索引
这里需要注意的是,查询的时候如果两个条件都用上了,但是顺序不同,如 city= xx and name =xx,那么现在的查询引擎会自动优化为匹配联合索引的顺序,这样是能够命中索引的.