创建高性能索引

0 概述

索引(mysql 也称之为key)是存储引擎用于快速查找到记录的一种数据结构。索引对于良好的性能非常关键,尤其当表中的数据量越来越大的时候,索引对性能的影响也愈发重要。在实际工作中,人们总是忽略或者过分强调索引的作用。

1 索引的本质

索引(Index)是帮助mysql 高效获取数据的数据结构。在关系型数据库(RDBMS)索引存储在硬盘上;从空间换取时间。

1.1 索引使用哪种数据结构

索引使用数据结构:hash,B+Tree
hash 使用就是哈希表。是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 由于innodb不支持hash索引,但是在某些情况下hash索引的效率很高,于是出现了adaptive hash index功能(不允许手动创建),但是通过上面的状态监控,可以计算其收益以及付出,控制该功能开启与否。默认开启,建议关掉,意义不大。可以通过 set global innodb_adaptive_hash_index=off/on 关闭和打开该功能。

show GLOBAL VARIABLES like "%innodb_adaptive_hash_index%"

创建高性能索引_第1张图片
B+Tree
为什么MySQL innodb 引擎使用B+Tree,而不使用B-Tree,二叉AVL树?
如下图所示AVL树,每个节点里面有一个关键数据。例如,查询005 需要IO 3次,。首先load 根节点004,然后在load 006 节点,然后在load 005 查询到数据。可见树的高度决定IO次数(当数据比较多树的高度会比较高),每次IO 关键字比较少,比较浪费。对于mysql innodb 每次和磁盘交互page,默认大小是16kb。可以如下命令查看

show  VARIABLES like "%innodb_page_size%"

创建高性能索引_第2张图片
节点数据格式
创建高性能索引_第3张图片
由上见二叉AVL树不适合这种场景 1)IO 次数多2)关键字内容少,因此B-Tree 诞生了。下面给出了B-Tree ,查询005 只需要1次IO 操作。

创建高性能索引_第4张图片
B-Tree 具
创建高性能索引_第5张图片
由上面可见,B-Tree 可以很好解决IO次数以及每次IO加载数据少的问题,那么为什么还会使用B+Tree 呢?首先看下B+Tree 特点1)所有的数据内容都在叶子节点 2)只有叶子节点有数据,且叶子节点有顺序的,这样比较有利于排序和范围查找。
创建高性能索引_第6张图片
创建高性能索引_第7张图片

1.2 聚集索引和非聚集索引

聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。数据行和相邻的键值紧凑地存储在一起,因为无法同时把数据行存放在两个不同的地方,所以一个表只能有一个聚集索引。Innodb 存储引擎中主键索引就是聚集索引,普通索引为非聚集索引。

1.3 回表

对于Innodb 存储引擎中,非主键索引中,他的叶子节点存放数据存放是主键值。因此对于select * from where col2=“c” ,就会存在回表操作 ,首先通过辅助索引查询到主键值,然后通过主键值去查询到行记录。因此不建议使用select * 操作,可能我们只获取主键Id。select id from where col2=“c” ,这样就不会出现回表了。
创建高性能索引_第8张图片

1.4 最左匹配原则

联合索引(col1,col2),最左优先,以最左边的为起点任何连续的索引都能匹配上。在创建联合索引的时候要考虑列的顺序,把选择性最好,最常使用的列放在最前面。联合索引是一颗树。

参考文献
[1]https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
[2] https://www.cnblogs.com/geaozhang/p/7252389.html

你可能感兴趣的:(数据库)