mysql B+树索引

数据库索引用于提高查询性能和数据访问效率。索引可以加速数据的查找和筛选,减少查询的时间复杂度。数据库索引有很多类型,这里不展开也不比较,只介绍最常见一种索引结构B+树索引。mysql中InnoDB引擎默认使用的就是BTREE索引。

B+树数据结构

B+树是一种常见的用来作为数据库索引的数据结构。下图是一张简单的B+树。
在这里插入图片描述

对照着图片来看下B+树的特点。B+树是一个平衡树(自平衡),所有的节点是有序的。这个特点使得B+树特别适合精确查找或者范围查找。

B+树不同于二叉树,每个节点存储数据数量可以是多个。这样存储数据可以大大降低树的高度,查找具体值时二分查找次数更少,效率更高。

另外B+树所有的数据都存放在最底层叶子节点上,非叶子节点上的数据会重复在叶子节点上存储一份。这样有序输出所有数据只需从左到右遍历所有的叶子节点。

前面两个特点其实是B树的特性,最后一个才是B+树特有的。B+树的插入和删除要保证操作后树依然有序。这可能会导致叶的分裂或合并。下面结合InnoDB引擎来具体看下Btree索引。

聚簇索引(Clustered Index)

聚簇索引的意思就是索引和对应的行数据存储在一块。在InnoDB表中,每个表都有一个聚簇索引来组织存储表数据。索引值有序的构建在索引所有非叶子节点上,然后所有的行数据存储在叶子节点上。

InnoDB优先使用主键索引来作为聚簇索引,如果没有主键,InnoDB会尝试使用第一个not null的唯一索引来作为聚簇索引,如果都没有。InnoDB会自动生成一个隐藏的索引列rowId来作为聚簇索引,这个列的大小大概5、6bytes。

所以说很多时候一张表定义一个自增的主键是非常有必要的,这样聚簇索引易于维护。如果主键是uuid不仅节点数据所占空间大,在插入或更新索引列时,由于不是顺序插入,如插入位置是一个已满的叶子节点,会导致页分裂,会导致行数据变的稀疏且占用更多的空间。

默认情况下B+树的一个索引页的大小是16kb,可以通过innodb_page_size参数来设置索引页的大小。修改该参数必须在数据库实例化之前完成。当向InnoDB聚簇索引中插入新记录时,InnoDB会尝试将页面的1/16留作未来插入和更新索引记录使用。如果按顺序(升序或降序)插入索引记录,则结果的索引页约有15/16已经被使用。如果以随机顺序插入记录,则页面的使用情况在1/2到15/16之间不等。

mysql> show variables like 'innodb_page_size';
+------------------+-------+
| innodb_page_size | 16384 |
辅助索引(Secondary Index)

除了聚簇索引,其它索引都是辅助索引。辅助索引可以是多列联合索引。辅助索引树上除了按照关联列进行按顺序存储外,还存有该行数据的主键值,便与查找到该行数据的所有内容。如果主键值比较长的话,同样的会导致辅助索引所占用空间变大。可见设置合适主键的重要性。

索引的维护

创建和删除索引有两种方式

ALTER TABLE 方式

ALTER TABLE 表名 ADD [KEY|INDEX] 索引名 (列名...)
ALTER TABLE 表名 DROP [KEY|INDEX] 索引名;

CREATE/DROP方式

CREATE [UNIQUE] INDEX 索引名 ON 表名 (列名,...);
DROP INDEX 索引名 ON 表名;

这里主键索引最好在建表语句中就指定好。还有唯一索引在

索引一般不修改,如果要修改索引最好是删除旧的然后再新增。

大小限制

一个表最大允许有64个辅助索引,索引key值最大长度是3072bytes(和row format有一定关系,默认DYNAMIC)。这个长度是字节具体类型要考虑字符集问题。如一个text类型要设置为索引列,需要设置前缀长度

CREATE TABLE test1 (ucode text ,UNIQUE INDEX (ucode(1000)));

如果使用u8字符集,1000前缀长度已经差不多最大 了。这里最大长度3072是在默认innodb_page_size 参数是16kb的前提下,如果调整页大小,索引key最大长度也需要等比例缩放(3kb/16kb)。如8kb索引key最大长度就是1536 bytes。

多列联合索引最大允许列16个,超过也会报错。

这里可能会问了,innodb一个页大小16kb,像text,blob这种可变大字段列如果超过了16kb是如何存储的。这里也有特殊处理,如果一行数据小于一个数据页的一半,则整行数据会存储在页内,如果超过了页的一半,可变长度列会被依次摘出存储在额外的空间(off-page)直到剩下行数据大小小于页的一般。这页间接的约束表定义时候不可变列最大长度合计不超过8kb(相对页大小16kb),更详细后面学习行记录存储时候再说,不同的行格式有些差异,这里只知道个大概就行,超长字段会被抽出存储在额外页空间。

索引信息查看
如何查看当前索引使用了多少页?

查看具体某一个索引大小每找到方法,查询一个表上所有索引大小可以使用SHOW TABLE STATUS命令来计算。

mysql> show table status where name='test' \G;
*************************** 1. row ***************************
           Name: test
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 16384
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2024-01-15 14:32:01
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment:

这里看到Index_length代表当前索引占用空间大小,除以innodb_page_size每页的大小就是索引占用页大小。

查看表上索引信息
mysql> show index from test \G;
*************************** 1. row ***************************
        Table: test
   Non_unique: 0
     Key_name: ucode
 Seq_in_index: 1
  Column_name: ucode
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:

Non_unique:是否是非唯一索引

Column_name:索引列名称

Collation:索引列排列规则,A升序,D是降序,null是不排序。Btree索引总是A。

Cardinality:基数趋势的意思,表示索引列上数据不重复数据数量。比如订单ID这种数据该值就会比大,但是订单状态这个值就会很小。Cardinality的值是一个统计数据,不是特别精确。执行ANALYZE TABLE 会更新该值。在一些连表操作上,Cardinality值越大该索引更可能被使用。

Sub_part:表示是否是部分前缀索引,如果使用的整列数据该值为null,如果是前缀索引,该值为前缀索引的前导长度。

索引原数据(metadata)

索引原数据存储在INFORMATION_SCHEMA.INNODB_SYS_INDEXES表中。

在这里插入图片描述

NAME:索引名称

TABLE_ID:对应表id,这个是INFORMATION_SCHEMA.INNODB_SYS_TABLES表的外键

TYPE: 3-聚簇索引、2-唯一索引、0-普通辅助索引、1-自动生成的聚簇索引

N_FIELDS:索引所关联的列

PAGE_NO:索引B+树上的根节点对应的索引页号

SPACE:表空间编号

MERGE_THRESHOLD:页合并的阈值,这里是百分比,如这里默认50%。如果一个索引页的数据量小于该阈值,如删除数据或更新索引列都会导致索引页数据变化,innodb会尝试将其与相邻的叶子节点进行合并。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/334751.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实验三 Oracle数据库的创建和管理

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

fastjson-BCEL不出网打法原理分析

FastJson反序列化漏洞 与原生的 Java 反序列化的区别在于,FastJson 反序列化并未使用 readObject 方法,而是由 FastJson 自定一套反序列化的过程。通过在反序列化的过程中自动调用类属性的 setter 方法和 getter 方法,将JSON 字符串还原成对…

我在代码随想录|写代码Day9之28. 实现 strStr(),459. 重复的子字符串,55. 右旋字符串(第八期模拟笔试)

博主介绍: 27dCnc 专题 : 数据结构帮助小白快速入门 28. 实现 strStr() 题目; 代码 1 class Solution { public: //KMPint strStr(string s, string t) {int n s.size(),mt.size();if(m0) return 0;s.insert(s.begin(), );t.insert(t.begin(), );vector<int> next(m1);…

容器技术1-容器与镜像简介

目录 1、容器与虚拟化 2、容器发展历程 3、镜像简介 4、镜像原理 &#xff08;1&#xff09;分层存储 &#xff08;2&#xff09;写时复制 &#xff08;3&#xff09;内容寻址 &#xff08;4&#xff09;联合挂载 1、容器与虚拟化 容器技术在操作系统层面实现了对计算机…

基于ORB算法的图像匹配

基础理论 2006年Rosten和Drummond提出一种使用决策树学习方法加速的角点检测算法&#xff0c;即FAST算法&#xff0c;该算法认为若某点像素值与其周围某邻域内一定数量的点的像素值相差较大&#xff0c;则该像素可能是角点。 其计算步骤如下&#xff1a; 1&#xff09;基于F…

个人实现的QT拼图游戏(开源),QT拖拽事件详解

文章目录 效果图引言玩法 拖拽概念基本概念如何在Qt中使用拖放注意事项 游戏关键问题总结 效果图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c6dd66befd314442adf07e1dec0d550c.png 引言 在学习QT demo时&#xff0c;发现有一个拼图demo&#xff0c;介绍拖…

LLVM 环境配置

这里选择下载源码, 然后编译的安装方式。 下载地址 (在这里可以找到多版本, 多平台的LLVM下载资源) # 解压源码 sudo tar xvf llvm-project-17.0.6.src.tar.xz # 新建安装目录 sudo mkdir -p /usr/local/llvm # 新建编译目录 sudo mkdir -p llvm-project-17.0.6.src/build #…

非线性最小二乘问题的数值方法 —— 狗腿法 Powell‘s Dog Leg Method (I - 原理与算法)

Title: 非线性最小二乘问题的数值方法 —— 狗腿法 Powell’s Dog Leg Method (I - 原理与算法) 文章目录 I. 前言II. 线搜索类型和信赖域类型1. 线搜索类型 —— 最速下降法2. 信赖域类型3. 柯西点 III. 狗腿法的原理1. 狗腿法的构建2. 狗腿法的优化说明3. 狗腿法的插值权重 I…

Java中打印图案最常用的25个图案程序

Java是公认的最流行的编程语言&#xff0c;因为它的简单性和多功能性。还可以使用它开发各种应用程序&#xff0c;包括Web、移动和桌面应用程序。此外&#xff0c;Java为开发人员提供了强大的工具来轻松高效地创建复杂的程序。Java最有前途的特性之一是它能够创建可以以特定格式…

Linux环境下部署Tomcat(详细图文)

目录 一、下载地址 1.服务器不能联网情况下载 2.服务器能够联网 二、安装 1. Tomcat解压 2. Tomcat目录说明&#xff1a; 3. 重命名解压后的文件名 4. 配置环境变量 5. 修改配置文件 6.启动Tomcat 7.访问Tomcat 8. 停止Tomcat 一、下载地址 1.服务器不能联网情况下…

PyTorch视觉工具箱:图像变换与上采样技术详解(1)

目录 Pytorch中Vision functions详解 pixel_shuffle 用途 用法 使用技巧 注意事项 参数 数学理论公式 示例代码及输出 pixel_unshuffle 用途 用法 使用技巧 注意事项 参数 数学理论公式 示例代码及输出 pad 用途 用法 使用技巧 注意事项 参数 示例代码…

SMT回流焊工艺之回流温度曲线

引言 在SMT生产流程中&#xff0c;如何控制回焊炉的温度是非常重要的一环&#xff0c;好的炉温曲线图意味着可以形成良好的焊点。 上一期分享&#xff08;SMT回流焊温度解析之锡膏焊接特性&#xff09;中&#xff0c;我们着重介绍了SMT回流工艺中的锡膏焊接部分。本期内容主要…

Leetcode2957. 消除相邻近似相等字符

Every day a Leetcode 题目来源&#xff1a;2957. 消除相邻近似相等字符 解法1&#xff1a;遍历 分类讨论 遍历字符串 word&#xff0c;比较相邻的 3 个元素 word[i - 1]、word[i] 和 word[i 1]&#xff0c;记 left_distance abs(mid - left)&#xff0c;right_distance…

大模型背景下计算机视觉年终思考小结(二)

1. 引言 尽管在过去的一年里大模型在计算机视觉领域取得了令人瞩目的快速发展&#xff0c;但是考虑到大模型的训练成本和对算力的依赖&#xff0c;更多切实的思考是如果在我们特定的小规模落地场景下的来辅助我们提升开发和落地效率。本文从相关数据集构造&#xff0c;预刷和生…

rust使用protobuf

前言 c,java,go 等直接是用 &#xff0c;具体就不说了&#xff0c;这章主要讲述rust 使用protobuf 这章主要讲述2种 1 > protoc protoc-gen-rust plugin 2> protoc prost-build 1&#xff1a;环境 win10 rustrover64 25-2 下载地址 https://github.com/protocolbu…

《WebKit 技术内幕》之四(3): 资源加载和网络栈

3. 网络栈 3.1 WebKit的网络设施 WebKit的资源加载其实是交由各个移植来实现的&#xff0c;所以WebCore其实并没有什么特别的基础设施&#xff0c;每个移植的网络实现是非常不一样的。 从WebKit的代码结构中可以看出&#xff0c;网络部分代码的确比较少的&#xff0c;它们都在…

2.4 网络层03

2.4 网络层03 2.4.7 路由表 1、什么是路由&#xff1f; 路由就是报文从源端到目的端的路径。当报文从路由器到目的网段有多条路由可达时&#xff0c;路由器可以根据路由表中最佳路由进行转发。 2、什么是路由表&#xff1f; 在计算机网络中&#xff0c;路由表&#xff08…

鸿蒙原生应用/元服务实战-AGC中几个菜单栏的关系

大家是否清楚AGC这几个菜单栏的相互关系&#xff1f; 我的元服务&#xff1a;点击后跳转到“我的应用”列表中的“HarmonyOS”页签&#xff0c;并且过滤出元服务。开发者可以在此模块中管理和运营元服务&#xff0c;例如创建元服务、发布元服务等。 我的应用&#xff1a;开发者…

2024最新Java高频面试题总结(附答案PDF)春招面试必备!

《Java面试全解析》1000道 面试题大全详解 本人是 2009 年参加编程工作的&#xff0c;一路上在技术公司摸爬滚打&#xff0c;前几年一直在上海&#xff0c;待过的公司有 360 和游久游戏&#xff0c;因为自己家庭的原因&#xff0c;放弃了阿里钉钉团队的 offer 回到了西安。 从…

Qt事件过滤

1.相关说明 监控鼠标进入组件、出组件、点击组件、双击组件的事件&#xff0c;需要重写eventFilter函数 2.相关界面 3.相关代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui-&…
最新文章