MYSQL 索引性能优化

151 阅读4分钟

MYSQL 索引性能优化

索引的本质

索引是帮助MYSQL 高效获取数据的排好序的数据结构.

image-20210204213920967

索引数据结构

  • 二叉树 会变成线性链表,效率低
  • 红黑树 数据量多时,IO磁盘效率低
  • hash 表
    • 对索引的key 进行一次hash计算就可以定位出数据存储的位置
    • 很多时间Hash 索引要比B+ 树索引更高效
    • 仅能满足 “=”,“IN”,不支持范围查询
    • hash 冲突问题

image-20210205203033287

  • B-tree

    • 叶子节点具有相同的深度,叶节点的指针为空

    • 所有索引元素不重复

    • 节点中的数据索引从左到右递增排列

      image-20210204222214291

  • B+tree

    • 非叶子节点不存储data,只存储索引,可以放更多的索引
    • 叶子节点包含所有索引字段
    • 叶子节点用指针连接,提高区间访问的性能,支持范围查找(20<col<50)
    • 高度大概为3到4,叶子节点可以存储2kw 个索引

    查找30 这个元素的过程,先把根节点加载到内存,根据二分查找的思想查找到15~56 这块的索引

    再根据二分查找的思想 查找到20~49这块索引,最后找到30这个元素。

myIsam存储引擎索引

image-20210205195352745

表中的数据都是存储在磁盘上的。每一行数据都有磁盘文件地址

表中的所有元素都是在文件中存放的。

image-20210205195942842

frm文件: 表的定义和结构

MYD文件:表所有数据

MYI文件:表所有索引

innodb 存储引擎索引

image-20210205195513759

image-20210205200654793

frm 文件:表的定义和结构

ibd 文件:表数据和索引,磁盘预读,会把查找的记录附近的数据都会查询出来。

聚集索引:叶子节点包含索引以及该行的其他数据字段

非聚集索引:根据索引需要跨多个文件去查找,比如myIsam 存储引擎中,需要从MYI 文件中到MYD文件 中查找数据(也称回表)

辅助索引: 叶子节点中存储主键值,每次查找数据时,根据索引找到叶子节点中的主键值,根据主键值再到聚簇索引中得到完整的一行记录

联合索引:联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。

(面试题)为什么建议Innob 表必须建主键,并且推荐使用整型的自增主键

如果没有建,数据库会自动找一列唯一的数据来当成主键索引,如果没有找到唯一的数据,会建一个伪藏列,这样会造成mysql资源比较紧张,带来很大的负担。

整型索引与字符串或者UUID相比而言,效率更高,占的空间较少。

自动递增:UUID 不是自动递增,可能存在节点分裂的情况,没有自增依次建节点效率高。

(面试题) 相比于叶子节点中存储行指针,二级索引存储主键值会占用更多的空间,那为什么要这样设计呢?

InnoDB在移动行时,无需维护二级索引,因为叶子节点中存储的是主键值,而不是指针。

(面试题) 那么InnoDB有了聚簇索引,为什么还要有二级索引呢?

聚簇索引的叶子节点存储了一行完整的数据,而二级索引只存储了主键值,相比于聚簇索引,占用的空间要少。当我们需要为表建立多个索引时,如果都是聚簇索引,那将占用大量内存空间,所以InnoDB中主键所建立的是聚簇索引,而唯一索引、普通索引、前缀索引等都是二级索引。

image-20210205203033287

mysql 最左前缀优化原则讲解

image-20210205205521545

组合索引中跳过name 后,age 是无序的,所以会进行全盘扫描。

待完 事务 ,MVCC,锁, 分库分表。