Mysql-索引结构
-
索引结构
- B树和B+树区别?
- 为了减少IO,索引会一次性加载么?
- 不会,在利用索引查询时,由于数据量和索引量的限制,不可能将全部的索引加载进内存,只能是逐一加载每一个磁盘页。因为磁盘页对应着索引树的节点。
- 为何说一般查找行记录只需要1-3次IO
- 因为一个页大小为16KB,按照聚簇索引结构来说。非叶子节点存放主键ID和子节点页号一,主键按bigInt类型占8个字节的话
- 一个非叶子页就能存放16*1024/8=2048个主键ID,因为页除了主键还有其他数据信息,这样按照一个目录页存放1000个主键算
- 叶子节点由于存放数据一页按照100个数据算
- 当B+树的层数为三层的时候总数据量就是O=10001000100=1亿
- 如果是四层结构那么总数据量就会达到1000亿,默认的根节点会在查询前就加载了,所以四层B+树1000亿的数据量只需要4-1=3次IO
- 为什么说B+树性能比B树好
- 因为B+树只有叶子节点存放数据,或叶子节点不存放数据,只存放建立索引字段。而B树,会将当前节点数据存放到当前页,目录页是会存放数据的。
- 这样会使目录页存放的数据更少,B+树的结构更加矮胖。越矮胖的树结构需要的IO次数少,并且B数由于指向子节点的数据重复的话会继续向下查找。导致查询次数不稳定,或多或少
- hash索引与B+树索引区别
- 由于hash是散列算法,导致它的数据存储是无序的。所以范围查找会慢,并且由于多值散列,联合索引会导致无法满足最左匹配索引,也无法进行关键字排序,也无法进行模糊匹配
- 等值匹配,当重复值多的话效率也会降低因为遇到 Hash 冲突时,需要遍历桶中的行指针来进行比较,找到查询的关键字非常耗时
- 由于存在冗余节点数据,Hash 索引会比较占内存
- 而B+树索引,目录页之间是双向列表,内部数据直接使用的是有序的单向列表,可以范围查找,匹配多字段索引,也可以模糊匹配
- Hash 索引与 B+ 树索引是在建索引的时候手动指定的吗
- Hash 索引与 B+ 树索引是在建索引的时候手动指定的。对于 InnoDB 存储引擎,默认采用 B+ 树索引,无法使用 Hash 索引。
- InnoDB 提供的自适应 Hash 是不需要手动指定的。如果是 Memory/Heap 和 NDB 存储引擎,是可以进行选择 Hash 索引的。
- MySQL如何实现的索引机制
- Mysql的Innodb和Myisam存储引擎默认使用的是B+树结构作为索引,而memory默认使用Hash索引
- 就Innodb来说:将索引分为聚簇索引和非聚簇索引,默认的主键索引就是聚簇索引,子节点存放最大或最小主键ID,叶子节点存放数据。
- 每个节点为一个数据页,数据页和数据页之间通过双向链表实现,节点内部为有序单向列表
- 如果建表时候没有指定主键,数据库会找是否有唯一非空索引字段,没有的话会创建一个隐式的自增ID作为聚簇索引键
- 非聚簇索引的话各节点存放的是建立索引字段最大或最小值,叶子节点存放主键ID和建立索引的字段
- InnoDB索引与MyISAM索引实现的区别是什么?
- 都使用的是B+树
- Innodb索引和数据存放在一起、聚簇索引叶子节点存放数据本身、非聚簇索引叶子节点存放数据指向
- myisam索引和数据分开存放、叶子节点存放行物理地址
- 一个表没创建索引,还会创建B+树吗?
- 没有显式创建索引,数据库会在内部生成一个隐式ID做主键,主键默认使用B+树需要注意的是,如果没有显式创建索引,那么这个聚集索引将无法提供高效的查询、排序和范围查询操作。
- 因为聚集索引是根据物理存储顺序进行组织的,而不是根据查询条件或数据相关性进行组织的。
- 说一下B+树索引实现原理(数据结构)
- 首先树结构是由数据页组成的,分为叶子节点和非叶子节点,叶子节点存放具体数据,非叶子节点存放子节点最小索引值,每个节点可存放多路子节点最小索引值,每层级节点通过页内维护上下指针,形成一个双向链表,页内数据为单向递增链表,如果引擎是Innodb叶子节点存放具体数据,如果是myisam叶子节点存放的是数据页地址。