前述
可能作为一个程序开发者,我们都知道数据库索引的重要性,我们可能会使用索引来优化数据库,但真正问到索引底层知识的时候我们可能又不知道说些什么了,在这里总结一下最近学习索引的相关知识与感受。
索引是什么、为什么使用
索引是一种与表有关的数据库结构、一个类似于目录的东西,它将无序的数据有序化,提高数据的访问速度与效率(增删改一般不推荐使用索引,因为需要改变索引,性能低下)。
索引的底层数据结构
索引的数据结构包含B+树和哈希表两种。
InnoDB存储引擎底层数据结构就是B+树,它采用聚集索引(主键创建的索引)。它的表数据文件本身就是一个B+树,树的叶子结点保存用户记录数据,其他层次的节点都属于内节点,内节点里存储的是目录项记录;
MyISAM存储引擎底层数据结构也是B+树,它采用的是非聚集索引(非主键创建的索引)。它将索引与数据分开存放,这种存储引擎的索引全部都是二级索引,在叶子节点处存储的是列 + 页号;
注意:
(1)二级索引:也称覆盖索引,以自定义的列的大小为页和记录的排序规则,在叶子节点处存储的记录内容是列 + 主键,在进行查找记录时,需要进行回表操作,也就是再通过主键查找一次。
强烈推荐阅读(MySQL索引)
(2)InnoDB也是支持哈希索引的,结构也就是哈希表,它底层的哈希表实现是透明的,是由InnoDB自己计算的。
索引的一些原则
- 最左前缀匹配原则
MySQL会一直向右匹配直到遇到范围查询,如(<、>、between、like等)
例如:(a=1 and b=2 and c>3 and d=4),此时只能命中前三个,不能命中d=4; - 避免冗余索引原则
冗余索引指的是索引的功能相同,能够命中 就肯定能命中 ,那么 就是冗余索引如(name,city )和(name )这两个索引就是冗余索引,能够命中后者的查询肯定是能够命中前者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引
索引的注意事项
- 避免where子句中对字段施加函数,造成无法命中索引。
- 使用InnoDB时使用与业务无关的自增主键作为主键,即使用逻辑主键而非业务主键。
- 将打算加索引的列设置为NOT NULL,否则会导致引擎放弃使用索引。
- 删除长时间未使用的索引(索引占据着一定的存储空间)。
- 使用limit offset查询缓慢时,借助索引提高性能。