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: testEngine: InnoDBVersion: 10Row_format: CompactRows: 0Avg_row_length: 0Data_length: 16384
Max_data_length: 0Index_length: 16384Data_free: 0Auto_increment: NULLCreate_time: 2024-01-15 14:32:01Update_time: NULLCheck_time: NULLCollation: utf8_general_ciChecksum: NULLCreate_options:Comment:

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

查看表上索引信息
mysql> show index from test \G;
*************************** 1. row ***************************Table: testNon_unique: 0Key_name: ucodeSeq_in_index: 1Column_name: ucodeCollation: ACardinality: 0Sub_part: NULLPacked: NULLNull: YESIndex_type: BTREEComment:
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.mzph.cn/news/636469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu设置每天定时关机

ubuntu设置每天定时关机 终端输入命令: sudo crontab -e输入密码,回车。 我这里使用nano作为编辑器,你可以选择vim。 在末尾输入以下命令: 59 23 * * * sudo -u root shutdown now设置:每天23:59分,电脑…

GitHub图床TyporaPicGo相关配置

本文作者: slience_me 文章目录 GitHub图床&Typora&PicGo相关配置1. Github配置2. picGo配置3. Typora配置 GitHub图床&Typora&PicGo相关配置 关于Typora旧版的百度网盘下载路径 链接:https://pan.baidu.com/s/12mq-dMqWnRRoreGo4MTbKg?…

SiamRPN代码研读

SiamRPN 1、概述 SiamRPN 是一种用于视觉目标跟踪的算法。它结合了 Siamese 网络(孪生网络)和 Region Proposal Network(区域提议网络)的概念。这种算法的主要目的是在视频序列中准确地跟踪单个目标。下面是它的一些关键特点&…

linux内核源码编译

centos7环境 iso选择 https://mirrors.tuna.tsinghua.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso 自带qemu,未实测是否可用 选择编译版本2.6 下载地址 遇到的编译错误解决 yum list | grep curses yum install ncurses-devel.x86_64 -y yum i…

python爬取图片(thumbURL和html文件标签分别爬取)

当查看源代码,发现网址在thumbURL之后时,用此代码: # 当查看源代码,发现网址在thumbURL之后时,用此代码:import requestsheaders {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121…

SQL Povit函数使用及实例

PIVOT函数常用于数据的行转列&#xff0c;同时也可以用此函数实现类似于Excel中的数据透视表的效果。 PIVOT函数 PIVOT 函数的基本语法如下&#xff1a; -- PIVOT 语法 SELECT <非透视的列>,[第一个透视的列] AS <列名称>,[第二个透视的列] AS <列名称>,.…

在iPhone或iPad和Windows PC之间复制和粘贴文本的几种方法,总有一种适合你

复制和粘贴文本一直是计算机和移动设备中最酷的省时功能之一。但这个过程的工作方式因你使用的设备和操作系统而异。 在iPhone(或iPad)和Mac之间复制和粘贴相对快速而简单。还有几个选项用于在Android设备和Windows之间移动内容。但是,如果你想在iPhone和Windows之间复制和…

旅游项目day07

目的地攻略展示 根据目的地和主题查询攻略 攻略条件查询 攻略排行分析 推荐排行榜&#xff1a;点赞数收藏数 取前十名 热门排行榜&#xff1a;评论数浏览数 取前十名 浏览数跟评论数差距过大&#xff0c;可设置不同权重&#xff0c;例如&#xff1a;将浏览数权重设置为0.3…

在微信公众号中加入ChatGPT聊天的方法

1 介绍 开源项目 "chatgpt-on-wechat" 支持通过微信公众号进行调用&#xff0c;这意味着用户可以在与公众号的交互中体验 ChatGPT。由于服务是部署在远端服务器上的&#xff0c;因此用户只需拥有一部手机&#xff0c;就可以在任何环境下与 ChatGPT 进行交流。例如&am…

linux下vsc的自动切换输入法解决方案

前言 个人使用的是Linux开发加上vsc编辑器&#xff0c;这两个东西一加中国开发者大致上就消失不见了&#xff0c;眼馋idea那个Smartinput很久了&#xff0c;赶上放假了&#xff0c;有空搞搞&#xff0c;如果后期有心情会做的通用点 安装 商店搜索SmartInputLinux安装 使用…

链表回文结构

链表回文结构 编写一个函数&#xff0c;检查输入的链表是否是回文的。 示例 1&#xff1a; 输入&#xff1a; 1->2 输出&#xff1a; false 示例 2&#xff1a; 输入&#xff1a; 1->2->2->1 输出&#xff1a; true 链表的回文结构&#xff0c;应该先找到中间节…

【Copula】最可能场景详解

基于Copula联合分布的最可能场景详解 最可能场景&#xff08;The most-likely scenario&#xff09;实例探讨参考 最可能场景&#xff08;The most-likely scenario&#xff09; 相应英文介绍原理介绍如下&#xff1a;&#xff08;出自论文J2020-Drought hazard transferabilit…

Helm Dashboard — Kubernetes 中管理 Helm 版本的 GUI

Helm Dashboard 通过提供图形用户界面&#xff0c;使在 Kubernetes 中管理 Helm 版本变得更加容易&#xff0c;这是许多开发人员所期望的。它可用于在 Kubernetes 中创建、部署和更新应用程序的版本&#xff0c;并跟踪其状态。 本文将探讨 Helm Dashboard 提供的特性和优势&am…

通过代理如何调通openai的api

调通openai的api 一、前提二、通过curl调通openai的api三、通过python调通openai的api 一、前提 会魔法上网本地运行代理软件&#xff0c;知道端口号&#xff08;如1081&#xff09;。 127.0.0.1:1081二、通过curl调通openai的api 如果在国外&#xff0c;没有qiang&#xff…

ChatGLM3报错:No chat template is defined for this tokenizer

使用官方提供的脚本创建ChatGLM3的DEMO&#xff1a; cd basic_demo python web_demo_gradio.py 出现效果异常问题&#xff1a; conversation [{role: user, content: 你好}, {role: assistant, content: 你好&#xff0c;有什么我可以帮助你的吗&#xff1f;\n\n<|im_end|…

23号资源——电力系统程序集合已提供下载资源

23号资源&#xff1a;程序集合包含9个程序&#xff08;经典电力系统经济调度程序&#xff1b;2解决带储&#xff1b;3智能微电网PSO优化算法&#xff1b;微电网调度等等&#xff0c;见资源描述&#xff09;资源-CSDN文库https://download.csdn.net/download/LIANG674027206/887…

docker安装 mysql 8.0.32

首先下载 mysql 其次如果虚拟机以前安过mysql 需要把mysql关闭 命令 永久关闭mysql 但是当前不生效 需要重启虚拟机 systemctl enable mysqld 如果不想重启虚拟机 可以执行 systemctl stop mysqld //指定版本 docker pull mysql:8.0.32 // 拉取最新的…

【linux】ps的基本使用

ps是linux中用于显示进程的工具&#xff0c;确切来说是显示活动进程的工具 ps的基本格式是 ps [选项] sh-3.2# ps --help ps: illegal option -- - usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]][-g grp[,grp...]] [-u [uid,uid...]][-p pid[,pid..…

[小程序]API、数据与事件

一、API ①事件监听API 以on开头&#xff0c;用来监听事件的触发&#xff08;如wx.inWindowResize&#xff09; ②同步API 以Sync结尾&#xff0c;且可以通过函数返回值获取&#xff0c;执行错误会抛出异常&#xff08;如wx.setStorageSync&#xff09; ③异步API 类似网页中的…

torchtext安装及常见问题

Pytorch 、 torchtext和Python之间有严格的对应关系&#xff1a; 在命令窗中安装torchtext pip install torchtext 注意这种安装方式&#xff0c;在pytorch版本与python版本不兼容时动会自动更新并安装pytorchcpu版本&#xff0c;安装的新版本pytorch可能会不兼容。慎用。 …