MYSQL 索引性能优化
索引的本质
索引是帮助MYSQL 高效获取数据的排好序的数据结构.
索引数据结构
- 二叉树 会变成线性链表,效率低
- 红黑树 数据量多时,IO磁盘效率低
- hash 表
- 对索引的key 进行一次hash计算就可以定位出数据存储的位置
- 很多时间Hash 索引要比B+ 树索引更高效
- 仅能满足 “=”,“IN”,不支持范围查询
- hash 冲突问题
-
B-tree
-
叶子节点具有相同的深度,叶节点的指针为空
-
所有索引元素不重复
-
节点中的数据索引从左到右递增排列
-
-
B+tree
- 非叶子节点不存储data,只存储索引,可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能,支持范围查找(20<col<50)
- 高度大概为3到4,叶子节点可以存储2kw 个索引
查找30 这个元素的过程,先把根节点加载到内存,根据二分查找的思想查找到15~56 这块的索引
再根据二分查找的思想 查找到20~49这块索引,最后找到30这个元素。
myIsam存储引擎索引
表中的数据都是存储在磁盘上的。每一行数据都有磁盘文件地址
表中的所有元素都是在文件中存放的。
frm文件: 表的定义和结构
MYD文件:表所有数据
MYI文件:表所有索引
innodb 存储引擎索引
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中主键所建立的是聚簇索引,而唯一索引、普通索引、前缀索引等都是二级索引。
mysql 最左前缀优化原则讲解
组合索引中跳过name 后,age 是无序的,所以会进行全盘扫描。
待完 事务 ,MVCC,锁, 分库分表。