数据库的索引是什么?
官网解释:索引是帮助实现高效获取数据的一种数据结构,就像一本书的目录。
索引常见的几种分类
作用在单列上和作用在多列上,区分单列索引和复合索引。
是否容许值重复,区分普通索引和唯一索引。 普通索引,容许定义的列出现重复值以及空值,该索引的设计目标就是快速查询; 唯一索引,容许重现空值,但不能出现重复的值; 主键索引,特殊索引,不能重复,不能存在空值。 全文检索,MyISAM 引擎中才有的。
mysql 的存储引擎 选择 innodb 才支持索引。
mysql 的 innodb 存储引擎为什么选择B+树,而不是二叉树、二叉平衡树或者B树?
B 树,在存储和查询上,有什么特点? 二叉树,在存储和查询上,有什么特点? 二叉平衡树,在存储和查询上,有什么特点? B+树,在存储和查询有什么特点? B树和B+树要区别点在哪里? mysql innodb 存储引擎,期望在数据查询时候能达到什么样效果?
把上述的几个疑问点,把它们整明白了,自然就明白innodb 为什么选择B+树了。
二叉树,在存储和查找上的特点:
如果它左子树不为空,则左子树上的值都小于根节点; 如果它右子树不为空,则右子树上的值都大于根节点; 在它的左、右子树上的查找,都是二叉查找。
二叉树的查找特点是保证每次查找都能减半而减少IO的开销,难点在于根节点存储什么值(存中位数)。二叉树的左右子树不一样高(出现左高右低,或者右高左低,在整个二叉树的查找容易出现不平衡)。
二叉平衡树,在存储和查询上的特点:
二叉平衡树,具备二叉树的特点,二叉平衡树的主要特点是,左子树和右子树的高度最多相差1,在插入数据时候,通过左旋、或者右旋来保证二叉树的平衡。解决了二叉树根节点存储问题。二叉平衡树的查找,接近二分查找,时间复杂度是 O(log2n)。
二叉平衡树的不足之处:
1、时间复杂度和树的高度紧密联系,树的高度很高,时间复杂度很大。百万级别的数据,查询需要0.2s多。
2、二叉平衡树也不支持范围找找,如果要支持范围查找需要从根节点开始遍历,查询效率不高。
思考:
我们要解决数据的存储问题、查找问题。 我们希望二叉树不要过高,通过减少IO开销,以此提高查找效率; 我们希望二叉树在插入的时候依然能保持树的平衡,不会影响二分查找。
从上面2个维度思考
B树
假如key为bigint=8字节,每个节点有两个指针,每个指针为4个字节,一个节点占用的空间16个字节(8+4*2=16)
因为在MySQL的InnoDB存储引擎一次IO会读取的一页(默认一页16K)的数据量,而二叉树一次IO有效数据量只有16字节,空间利用率极低。为了最大化利用一次IO空间,一个简单的想法是在每个节点存储多个元素,在每个节点尽可能多的存储数据。每个节点可以存储1000个索引(16k/16=1000),这样就将二叉树改造成了多叉树,通过增加树的叉树,将树从高瘦变为矮胖。构建1百万条数据,树的高度只需要2层就可以(1000*1000=1百万),也就是说只需要2次磁盘IO就可以查询到数据。磁盘IO次数变少了,查询数据的效率也就提高了。
B树,是一种多叉树平衡树。
B树,在存储和查找上的特点:
1、B树的节点中存储着多个元素,每个内节点有多个分叉。
2、节点中的元素包含键值和数据,节点中的键值从大到小排列。也就是说,在所有的节点都储存数据
3、父节点当中的元素不会出现在子节点中。
4、所有的叶子结点都位于同一层,叶节点具有相同的深度,叶节点之间没有指针连接。
B树的不足:
1、B树不支持范围查找,
2、data块存储行记录,如何一个表列很多,占用空间很大,一页中存储的数据量就很少,树的高度会增加,查询效率降低。
B+树
1、B树:非叶子节点和叶子节点都会存储数据。
2、B+树:只有叶子节点才会存储数据,非叶子节点至存储键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表。
B+树的最底层叶子节点包含了所有的索引项。B+树在查找数据的时候,由于数据都存放在最底层的叶子节点上,所以每次查找都需要检索到叶子节点才能查询到数据。所以在需要查询数据的情况下每次的磁盘的IO跟树高有直接的关系,但是从另一方面来说,由于数据都被放到了叶子节点,所以放索引的磁盘块所存放的索引数量是会跟着增加的,所以相对于B树来说,B+树的树高理论上情况下是比B树要矮的。也存在索引覆盖查询的情况,在索引中数据满足了当前查询语句所需要的全部数据,此时只需要找到索引即可立刻返回,不需要检索到最底层的叶子节点。
innodb 的索引优化
1、避免回表
2、联合索引使用