钜形不锈钢水箱 发表于 2024-7-30 20:54:36

数据库-索引

索引概述

索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库体系还维护着满足
特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 如许就可以在这些数据结构
上实现高级查找算法,这种数据结构就是索引。
 
特点
https://img-blog.csdnimg.cn/48cdd15ec6754ef4b95db51f4e8515b7.png
 
索引结构
MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,重要包含以下几种:
https://img-blog.csdnimg.cn/24c1883e1309492da04a60938cfe9ce9.png
 
上述是MySQL中所支持的所有的索引结构,接下来,我们再来看看不同的存储引擎对于索引结构的支持
环境。
https://img-blog.csdnimg.cn/cdd95d936a4c455aafc5ce1525b0a2a7.png
注意: 我们平常所说的索引,假如没有特别指明,都是指B+树结构组织的索引。
 
 二叉树

假如说MySQL的索引结构采用二叉树的数据结构,比较理想的结构如下:
https://img-blog.csdnimg.cn/6566fc0d397544bb886f6b78ef2a2264.jpg
 
所以,假如选择二叉树作为索引结构,会存在以下缺点:
顺序插入时,会形成一个链表,查询性能大大降低。
大数据量环境下,层级较深,检索速度慢。
 
此时大家可能会想到,我们可以选择红黑树,红黑树是一颗自平衡二叉树,那如许纵然是顺序插入数
据,最终形成的数据结构也是一颗平衡的二叉树,结构如下:
https://img-blog.csdnimg.cn/4e44ee9b26dc49eca7cab84a9ffbe89e.png
 
纵然如此,由于红黑树也是一颗二叉树,所以也会存在一个缺点:
大数据量环境下,层级较深,检索速度慢。
所以,在MySQL的索引结构中,并没有选择二叉树或者红黑树,而选择的是B+Tree,那么什么是
B+Tree呢?在详解B+Tree之前,先来介绍一个B-Tree。
B-Tree
B-Tree,B树是一种多叉路衡查找树,相对于二叉树,B树每个节点可以有多个分支,即多叉。
以一颗最大度数(max-degree)为5(5阶)的b-tree为例,那这个B树每个节点最多存储4个key,5
个指针:
https://img-blog.csdnimg.cn/ce8603bf6fd84a2da9be7afaeeb6bcdb.png
 
知识小贴士: 树的度数指的是一个节点的子节点个数。
可视化网站 https://www.cs.usfca.edu/~gall
 
特点:
5阶的B树,每一个节点最多存储4个key,对应5个指针。
一旦节点存储的key数目到达5,就会裂变,中间元素向上分裂。
在B树中,非叶子节点和叶子节点都会存放数据。
B+Tree
B+Tree是B-Tree的变种,我们以一颗最大度数(max-degree)为4(4阶)的b+tree为例,来看一
下其结构示意图:
https://img-blog.csdnimg.cn/679a096658da4a8394d90327c4e91bd2.png我们可以看到,两部分:
绿色框框起来的部分,是索引部分,仅仅起到索引数据的作用,不存储数据。
赤色框框起来的部分,是数据存储部分,在其叶子节点中要存储详细的数据。
 
 最终我们看到,B+Tree 与 B-Tree相比,重要有以下三点区别:
   所有的数据都会出现在叶子节点。
叶子节点形成一个单向链表。
非叶子节点仅仅起到索引数据作用,详细的数据都是在叶子节点存放的。
上述我们所看到的结构是标准的B+Tree的数据结构,接下来,我们再来看看MySQL中优化之后的
B+Tree。
 
MySQL索引数据结构对经典的B+Tree举行了优化。在原B+Tree的基础上,增长一个指向相邻叶子节点
的链表指针,就形成了带有顺序指针的B+Tree,进步区间访问的性能,利于排序。
https://img-blog.csdnimg.cn/4b1232d2d29f4777b22cf298575ab869.png
 
 Hash
MySQL中除了支持B+Tree索引,还支持一种索引类型---Hash索引。
1). 结构
哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在
hash表中。
https://img-blog.csdnimg.cn/baf77efcebaf4d47829eea3efbd91136.png
 2). 特点
A. Hash索引只能用于对等比较(=,in),不支持范围查询(between,>,< ,...)
B. 无法利用索引完成排序操作
C. 查询效率高,通常(不存在hash冲突的环境)只需要一次检索就可以了,效率通常要高于B+tree索

3). 存储引擎支持
在MySQL中,支持hash索引的是Memory存储引擎。 而InnoDB中具有自适应hash功能,hash索引是
InnoDB存储引擎根据B+Tree索引在指定条件下自动构建的。
 
思考题: 为什么InnoDB存储引擎选择利用B+tree索引结构?
https://img-blog.csdnimg.cn/ecce7ad8f9f643f9a4c0bb2f3fa4ec73.png
 索引分类

MySQL数据库,将索引的详细类型重要分为以下几类:主键索引、唯一索引、通例索引、全文索引
https://img-blog.csdnimg.cn/f0f1831aee4b4741ae3a67ba66bba830.png
  聚集索引&二级索引
而在在InnoDB存储引擎中,根据索引的存储情势,又可以分为以下两种:
https://img-blog.csdnimg.cn/7f5c3f8acf13428582b0da56804e1e1d.jpg
 
聚集索引选取规则:
 
假如存在主键,主键索引就是聚集索引。
假如不存在主键,将利用第一个唯一(UNIQUE)索引作为聚集索引。
假如表没有主键,或没有符合的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索
引。
 
聚集索引和二级索引的详细结构如下:
https://img-blog.csdnimg.cn/60fbd981a6504f6d9e3506a11ba1bff6.png
 

[*]聚集索引的叶子节点下挂的是这一行的数据 。
[*]二级索引的叶子节点下挂的是该字段值对应的主键值。
接下来,我们来分析一下,当我们执行如下的SQL语句时,详细的查找过程是什么样子的。
详细过程如下:
https://img-blog.csdnimg.cn/f3d52b2c4c354b509a59e10c8b15b009.png
 
①. 由于是根据name字段举行查询,所以先根据name='Arm'到name字段的二级索引中举行匹配查根据name字段举行查询,但是在二级索引中只能查找到 Arm 对应的主键值 10。
②. 由于查询返回的数据是*,所以此时,还需要根据主键值10,到聚集索引中查找10对应的记录,最
终找到10对应的行row。
③. 最终拿到这一行的数据,直接返回即可。
   回表查询: 这种先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取
数据的方式,就称之为回表查询。
思考题:
以下两条SQL语句,谁人执行效率高? 为什么?
A. select * from user where id = 10 ;
B. select * from user where name = 'Arm' ;
备注: id为主键,name字段创建的有索引;
解答:
A 语句的执行性能要高于B 语句。
因为A语句直接走聚集索引,直接返回数据。 而B语句需要先查询name字段的二级索引,然
后再查询聚集索引,也就是需要举行回表查询。
思考题:
InnoDB主键索引的B+tree高度为多高呢?
假设:
一行数据巨细为1k,一页中可以存储16行如许的数据。InnoDB的指针占用6个字节的空
间,主键纵然为bigint,占用字节数为8。
高度为2:
n * 8 + (n + 1) * 6 = 16*1024 , 算出n约为 1170
1171* 16 = 18736
也就是说,假如树的高度为2,则可以存储 18000 多条记录。
高度为3:
1171 * 1171 * 16 = 21939856
也就是说,假如树的高度为3,则可以存储 2200w 左右的记录。
 索引语法

1). 创建索引
2). 查察索引
3). 删除索引
案例演示:
https://img-blog.csdnimg.cn/e6686d0a8f714065b0fd16fe307d241b.png
 https://img-blog.csdnimg.cn/451477764f6e4f0eac619d2450c8a3e6.png
https://img-blog.csdnimg.cn/a079d97b6e274f4b87eb41a43a18298e.png 
https://img-blog.csdnimg.cn/d16d3b6d4b23433e9eadc893fe787ad0.png 
https://img-blog.csdnimg.cn/a02bb4cb71f54c84837f0eb6a88917c2.jpg 
    
连合索引(Composite Index),也称组合索引、复合索引,是指在一个数据库表中建立多个列上的索引,而这些列共同构成了一种索引。连合索引可以进步查询效率,特别是在多个列参与查询时。
举个例子,假如有一个包含姓名、年岁、地址等信息的用户表,我们可以在姓名、年岁、地址这三个列上建立连合索引。如许在查询时,就可以同时利用这三个列上的索引,举行高效的数据查询。
可以利用连合索引的场景通常是在多个列上常常被一起利用作为查询条件,而单独只用其中一个列建立索引结果较差。需要注意的是,连合索引的列的顺序也会影响查询效率,所以在建立连合索引时应该根据实际环境举行优化选择。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 数据库-索引