MySql索引的介绍和认识:
MySql索引的本质:是帮助数据库高效获得数据的排好序的数据结构。
学习数据结构网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
MySql索引数据结构:B-Tree 或者hash
B-Tree
- 叶节点具有相同的深度,叶节点的指针为空
- 所有索引元素不重复
- 节点中的数据索引从左到右递增排列
B+Tree(变种)
- 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能
mysql5.5 数据库:
Mysql5.5版本数据库执行此命令查询 数据库表存放地址:
SELECT @@datadir
所有的数据库文件存放地址
MyISAM存储引擎 文件存放后缀格式
- *.frm (from)文件 是描述表的框架信息
- *.myd 文件 是描述表的行数据信息
- *.myi 文件 是描述表的索引信息
InnoDB存储引擎 文件存放后缀格式
只有两个文件
- *.frm (同上)
- ibd (存放数据和索引)
MySQL索引实现:
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,主要分为MyISAM和InnoDB两个存储引擎的索引实现方式。
索引最后是以表的存储引擎来区别的
MyISAM存储引擎索引实现算法:
MyISAM索引文件和数据文件是分离的(所以称为非聚集索引业绩)使用B+Tree作为索引结构,叶节点的data域存放的是数据所在行记录的地址,如图:
每一行数据都有一个地址存放在叶节点,指向表的每一行数据 ,来实现索引
InnoDB索引实现算法
虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。第一个重大区别是InnoDB的数据文件本身就是索引文件。**从上文截图知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
推荐使用整型的自增主键是为了,更快的查找到叶节点的数据。如果表里没有主键,会使用唯一主键索引存储到叶节点,如果表里唯一主键不存在,会使用表的唯一行 compact(行格式,若innodb表没有定义主键,每行还会增加一个6字节的rowid列。https://www.pianshen.com/article/4763708114/)来存储来叶节点。
每一个磁盘块在mysql中是一个页,页大小是固定的,innodb的默认的页大小是16k,每个索引会分配在页上的数量是由字段的大小决定。当字段值的长度越长,每一页上的数量就会越少,因此在一定数据量的情况下,索引的深度会越深,影响索引的查找效率。
如图 Aike 是索引 后面空白的 就是一个指针(这里可以存储一个索引也可以存储多个索引), 而一个存储索引指针的内存大小默认是16k。
Hash索引
是表数据的某一个值进行hash运算结果得到的值,存到Hash表,通过索引来对比hash值来比对查找数据所在行的文件地址指针。
- 优点:hash 索引的查询等值数据 是比 B-tree的速度快的
- 缺点: 当我们要进行范围查找的时候 “select * from user where age>16” ,这样的业务场景 Hash索引是不很好支撑的
联合索引
两个或更多个列上的索引被称作联合索引,联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
- 1、需要加索引的字段,要在where条件中
- 2、数据量少的字段不需要加索引
- 3、如果where条件中是OR关系,加索引不起作用
- 4、符合最左原则