MySQL索引(B树、B+树)

article/2025/9/9 0:03:12

目录

  • 简介
  • 索引结构(树)
    • 为什么用树,而不用哈希表
    • BTree索引
    • B+Tree索引
    • 聚簇索引与非聚簇索引
  • 索引分类
  • 性能分析
    • 索引创建场景

简介

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引是数据结构。

在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。

一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。

优点:
1、类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本。
2、通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

缺点:
1、虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。
2、实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的

索引举例:(用树结构做索引)
左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址。
在这里插入图片描述
为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。

索引结构(树)

如何通过索引加快数据库表的查询速度呢?为了方便讲解,我们限定于数据库表只包含下面这样两个查询需求:
1、select* from user where id=1234;
2、select *from user where id>1234 and id<2345;(按区间)

为什么用树,而不用哈希表

哈希表按值查询的性能很好,时间复杂度是O(1),但它不能支持按照区间快速查找数据,因此无法满足要求。同理,尽管平衡二叉查找树查询性能很高,时间复杂度为O(logn),而且对树进行中序遍历,可以输出有序的数据序列,但也无法满足按照区间快速查找数据的需求。

为了支持按照区间快速查找数据,我们对二叉查找树进行改造,将二叉查找树的叶子节点用链表串起来,如果要查找某个区间的数据,只需要用区间的起始值,在树中进行查找,当定位到有序链表中的某个节点之后,再从这个节点开始顺着有序链表往后遍历,直到有序链表中的节点数据值大于区间终止值为止。
在这里插入图片描述

又因为树上的很多操作的时间复杂程度与树的高度成正比,降低的树的高度,就能减少磁盘IO操作。因此我们把索引构建成m叉树(m>2),详细介绍可看后文。

BTree索引

在介绍B+树之前,先来了解一下B树。
在这里插入图片描述
1、初始化介绍
一颗b树,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3。P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。

注意:
真实的数据只存在于叶子节点,即3、5、9、10、13、15、28、29、36、60、75、79、90、99。(而且是多条数据组成的数据区间:3~ 5,… … ,90~ 99)

非叶子节点不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

2、查找过程
如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。

B+Tree索引

B+树和B树类似,B+树是B树的改进版。
即:m叉查找树与有序链表构建成的树就是B+树,也就是要存储的树索引
在这里插入图片描述

如图:B+树和B树的主要区别有以下两点:
1、B+树的叶子节点用链表来串联。
查找某个区间的数据,只需要用区间的起始值,在树中进行查找,当定位到有序链表中的某个节点之后,再从这个节点开始顺着有序链表往后遍历,直到有序链表中的节点数据值大于区间终止值为止。

2、B+树中的任何节点都不存储真实数据,只是用来索引。
B树直接通过叶子节点获取到数据;而B+树每个叶子节点存储数据行的键值和地址信息,当查询到某个叶子节点时,通过叶子节点的地址找到真实的数据信息。

聚簇索引与非聚簇索引

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。
术语‘聚簇’表示数据行和相邻的键值聚簇的存储在一起。

聚簇索引的好处:
按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不不用从多个数据块中提取数据,所以节省了大量的io操作。

聚簇索引的限制:
1、对于mysql数据库目前只有innodb数据引擎支持聚簇索引,而Myisam并不支持聚簇索引。
2、由于数据物理存储排序方式只能有一种,所以每个Mysql的表只能有一个聚簇索引。一般情况下就是该表的主键。
3、为了充分利用聚簇索引的聚簇的特性,所以innodb表的主键列尽量选用有序的顺序id,而不建议用无序的id,比如uuid这种。

如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致。
在这里插入图片描述

索引分类

单值索引
即一个索引只包含单个列,一个表可以有多个单列索引

随表一起建索引:
CREATE TABLE customer (
id INT(10) UNSIGNED  AUTO_INCREMENT ,
customer_no VARCHAR(200),
customer_name VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name)
);单独建单值索引:
CREATE  INDEX idx_customer_name ON customer(customer_name); 删除索引:
DROP INDEX idx_customer_name  on customer;

唯一索引
索引列的值必须唯一,但允许有空值

随表一起建索引:
CREATE TABLE customer (
id INT(10) UNSIGNED  AUTO_INCREMENT ,
customer_no VARCHAR(200),
customer_name VARCHAR(200),PRIMARY KEY(id),KEY (customer_name),UNIQUE (customer_no)
);单独建唯一索引:
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no); 删除索引:
DROP INDEX idx_customer_no on customer ;

主键索引
设定为主键后数据库会自动建立索引,innodb为聚簇索引

随表一起建索引:
CREATE TABLE customer (
id INT(10) UNSIGNED  AUTO_INCREMENT ,
customer_no VARCHAR(200),
customer_name VARCHAR(200),PRIMARY KEY(id) 
);CREATE TABLE customer2 (
id INT(10) UNSIGNED   ,
customer_no VARCHAR(200),
customer_name VARCHAR(200),PRIMARY KEY(id) 
);单独建主键索引:
ALTER TABLE customer add PRIMARY KEY customer(customer_no);  删除建主键索引:
ALTER TABLE customer drop PRIMARY KEY ;  修改建主键索引:
必须先删除掉(drop)原索引,再新建(add)索引

复合索引
即一个索引包含多个列

随表一起建索引:
CREATE TABLE customer (
id INT(10) UNSIGNED  AUTO_INCREMENT ,
customer_no VARCHAR(200),
customer_name VARCHAR(200),PRIMARY KEY(id),KEY (customer_name),UNIQUE (customer_name),KEY (customer_no,customer_name)
);单独建索引:
CREATE  INDEX idx_no_name ON customer(customer_no,customer_name); 删除索引:
DROP INDEX idx_no_name  on customer ;

性能分析

索引创建场景

哪些情况需要创建索引
1、主键自动建立唯一索引
2、频繁作为查询条件的字段应该创建索引
3、查询中与其它表关联的字段,外键关系建立索引
4、单键/组合索引的选择问题, 组合索引性价比更高
5、查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
6、查询中统计或者分组字段

哪些情况不要创建索引
1、表记录太少
2、经常增删改的表或者字段
原因:提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件
3、Where条件里用不到的字段不创建索引
4、过滤性不好的不适合建索引


http://chatgpt.dhexx.cn/article/c99TnIjG.shtml

相关文章

MySQL B+树相对于B树的区别及优势:

部分参考&#xff1a;B树和B树的区别 MySQL为什么使用树结构&#xff1f; 文件很大&#xff0c;不可能全部存储在内存中&#xff0c;故要存储到磁盘上索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数&#xff08;为什么使用B-/Tree&#xff0c;还跟磁盘存取原理有关&am…

B树索引

B-Tree索引是最常见的索引结构&#xff0c;如oracle和mongodb的索引都是B-Tree&#xff0c;而mysql的索引类型是BTree 一、B树索引的结构 B-树索引是基于二叉树结构的。B-树索引结构有3个基本组成部分&#xff1a;根节点、分支节点和叶子节点。其中根节点位于索引结构的最顶端…

什么是B树

1.什么是B树 B树又称为多路平衡查找树&#xff0c;B树中所有结点的孩子节点数的最大值称为B树的阶&#xff0c;通常用m表示。 2.B树的特性 一颗m阶B树或为空树&#xff0c;或为满足如下特性的m叉树&#xff1a; 1&#xff09;树中每个结点至多有M棵子树&#xff08;即至多含有…

图解B树构建过程

1.B树结构同时满足以下特性 每个节点最多包含n个孩子&#xff0c;即n叉树&#xff1b;除了根节点和叶子节点外&#xff0c;每个节点至少有ceil(n/2)个孩子&#xff08;ceil是向上取整&#xff09;&#xff1b;若根节点不是叶子节点&#xff0c;则至少有两个孩子&#xff1b;所…

了解B树的删除

文章目录 1. 删除操作第一种情况第二种情况第三种情况 2. C示例3. 删除复杂度参考文档 在本教程中&#xff0c;您将学习如何从B树中删除键。此外&#xff0c;您还可以找到C语言的示例。     删除B树上的元素包括三个主要事件&#xff1a;搜索要删除的键所在的节点、删除键和…

B树的插入、删除操作

一、简介 B树是什么&#xff1f; 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适用于外查找的树&#xff0c;它是一种平衡的多叉树&#xff0c;称为B树&#xff08;或B-树、B_树&#xff09;。 一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树。它或者是空树…

数据结构-B树删除示例

数据结构学习-B树删除示例 1、B树简介2、在线可视化生成B树工具3、B树删除规则4、B树删除示例4.1、删除非根结点示例4.2、删除根结点示例 1、B树简介 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适用于外查找的树&#xff0c;它是一种平衡的多叉树&#xff0c;称为B树&a…

B树-多路平衡查找树

B树 B树一个m阶B树的具有的特征&#xff08;或必须满足的条件&#xff09;B树的查找B树插入元素(一定是在叶子节点插入)1.插入后&#xff0c;没有破坏B树的规则2.插入后&#xff0c;叶子节点元素超过m-1个 B树删除元素1.删除叶子节点上的元素&#xff0c;没有破坏规则2.删除叶子…

B树、B+树详解

B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;目前理解B的意思为平衡。 概念 首先&#xff0c;B树不要和二叉树混淆&#xff0c;在计算机科学中&#xff0c;B树是一种自平衡树数据结构&#xff0c;它维护有序数据并允许以对数时间进行搜索&#xff0c;顺…

【B树及B树的基本操作】

文章目录 1.B树的定义和特性2.B树的性质3.B树创建的过程。4.B树的删除5.总结 1.B树的定义和特性 B树是一种平衡的多路查找树。 一棵m阶的B树&#xff08;B树中所有结点的孩子个数的最大值为m)&#xff0c;或为空树&#xff0c;或为满足下列特性的m叉树&#xff1a; (1) 树中每…

B树和B+树的区别

文章目录 简述写在前面1、B树2、B树 深入浅出B树B树深入B-树的查找 B 树B树概述 B-树和B树的区别拓展&#xff1a;MySQL为什么使用B-Tree&#xff08;BTree&#xff09;&& 存储知识存储数据最小单元主存存取原理磁盘存取原理 总结 简述 写在前面 大家在面试的时候&am…

B树(B-树)详解

B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;而国内很多人喜欢把B-tree译作B-树&#xff0c;B-tree就是指的B树。 B-树容易让人误解,建议大家用B树称呼, 本文以下直称B树 这篇介绍概念, 优点应用等, B树的描述和增删改查请到隔壁我写的另一篇(篇幅较长…

数据结构 —— B树

文章目录 1、B树的定义1.1、B树的特性1.2、B树的高度1.3、性能分析1.4、B树的补充说明1.5 、B树、B-树 、B-tree、B tree的区别 2、B树的插入操作以5阶B树为例&#xff0c;介绍B树的插入操作&#xff0c; 3、 B树的删除操作以5阶B树为例&#xff0c;介绍B树的删除操作 4、B树相…

B树和B+树详解

B树、B树看这一篇就够了 [TOC](B树、B树看这一篇就够了) 引言B树什么是B树以及B树是怎么来的B树的基本性质B树的新增和删除B树的插入B树的删除 B树什么是B树以及为什么要有B树B树的基本性质B树的查找 B树与B树的比较B树的优势B树的优势两者的细节对比 B树与B树在实际代码中的应…

B-树(B树)详解

https://www.jianshu.com/p/7dedb7ebe033 具体讲解之前&#xff0c;有一点&#xff0c;再次强调下&#xff1a;B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;而国内很多人喜欢把B-tree译作B-树&#xff0c;其实&#xff0c;这是个非常不好的直译&#xf…

B树和B+树

目录 一、BST树到AVL树到B树的简介 1.1 BST树 --- 二叉排序树 1.2 AVL树 --- 平衡二叉树 1.3 B树 --- 平衡多路查找树 1.3.1 B树的查找结点过程 1.3.2 B树的添加结点过程&#xff08;和结点分裂过程&#xff09; 1.3.3 B树的删除结点过程 二、B树 2.1 B树和B树 一…

在群晖NAS部署_开源在线项目任务管理工具【dooTask】

一、dooTask简介 1.1、说明 Dootask 是一款由国人开源的轻量级在线项目任务管理工具&#xff0c;它提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时通讯IM&#xff0c;文件管理等功能。基于PHP与Vue编写&#xff0c;遵守AGPL3.0开源协议。 1.2、特…

软件项目管理的重点知识

软件项目管理的重点知识 1.软件项目管理概述 1.1项目是什么 项目是为了创造一个唯一的产品或提供一个唯一的服务而进行的临时性的努力。 1.2常见的项目 生活中的项目 生日聚会野餐活动集体婚礼 大项目 微软的操作系统阿波罗计划神州飞船计划鸿蒙操作系统开发一个网站运…

推荐八款好用的项目管理工具

要想取得项目成功&#xff0c;避不开包括计划、执行、监控等。使用项目管理工具可以帮助项目经理制定项目计划&#xff0c;监控项目执行&#xff0c;跟踪项目进度。 1、进度猫 进度猫是国产的一款项目管理工具以甘特图为向导&#xff0c;基于任务清单todolist&#xff0c;支持…

工程项目管理软件有哪些?这六款很好用!

工程项目管理软件哪个好用&#xff1f;这六款很不错&#xff01; 在现代社会中&#xff0c;软件已经成为了企业信息化、项目管理等方面必不可少的工具。尤其是对于工程项目管理而言&#xff0c;借助软件进行协同、计划、控制等方面的工作&#xff0c;已经成为了必要的手段。但…