索引的类型
- Hash索引、有序数组索引、B树索引、全文索引
索引的优点
- 大大减少了服务器需要扫描的数据量
- 帮助服务器避免排序和临时表
- 索引可以将随机IO变为顺序IO
索引的数据结构
- 聚集索引
- 数据存储在叶子节点上
- 数据和索引是存储在一起的
- 非聚集索引
- 叶子节点存储的是主键值(二级索引)
- 和实际数据存储是分离的
索引优化思路详解
- 用独立的列作为索引
- 在索引列上进行计算操作、函数操作会导致索引失效。
- 联合索引
- 选择合适的索引列顺序
- 如果首列查询为范围查询,则不会用到后边的索引列
- 聚簇索引
- 根据主键获取数据比非聚簇索引少一次磁盘IO,获取数据更快,使用覆盖索引,可以直接从叶子节点拿到主键值
- 插入速度依赖顺序插入
- 数据行移位
- 可能导致页分裂
- 导致已经刷新到磁盘的页需要被重新加载
- 可能会导致数据碎片
- 二级索引需要两次索引查找
- 索引覆盖
- 只能在B-Tree索引中使用。
- Extra中显示Use Index。
- 使用索引来做排序
- Explain 出来的结果type为index。B-Tree索引是有序的。
- 如果不是索引覆盖的话,Mysql根据索引每查询到一条数据,都会进行一次回表,而此时的回表操作属于是随机IO。因此顺序的读取数据,速度通常比顺序的全表扫描要慢。
索引优化的原则
- 避免单行访问,尽量每一次加载数据块都可以访问一批数据
- 按顺序访问数据,避免额外的排序操作,顺序IO相比于随机IO要快的多,少了很多次磁盘寻道等过程(SDD硬盘)。
- 尽量使用索引覆盖。
普通索引和唯一索引的区别
- 查询
- 普通索引,查找到第一条记录,会查找下一条记录,直到碰到不满足条件的为止
- 唯一索引,查找到这一条记录就直接返回。
- 查询区别:
- 因为InnoDB是按页来加载索引的,每页16KB,多的一次查找相当于是多了一次指针寻找和一次计算,影响很小。
- 更新
- 要更新的目标页在内存中
- 唯一索引:判断是否有键值冲突,执行sql
- 普通索引:找到位置插入值,语句结束
- 要更新的目标页不在内存中
- 唯一索引:将数据加载到内存中,判断是否有键值冲突,执行sql
- 普通索引:将更新写入changeBuffer,语句结束
- 要更新的目标页在内存中
RedoLog与ChangeBuffer的区别
- RedoLog主要作用是在写数据的时候,通过更新内存+记录RedoLog防止随机写磁盘。
- ChangeBuffer的作用主要是在更新数据的时候,通过记录更新操作,避免把数据加载到内存,再更新内存的随机读磁盘操作。
ChangeBuffer不适用的场景
- 写完立马就要读的场景。
- 因为写完立刻就要读,会导致需要马上从磁盘读取,加载到内存,然后进行对应的merge操作。没有起到减少随机读取的效果。