【MySQL】索引——索引的实现、B+ vs B、聚簇索引 VS 非聚簇索引、索引操作、创建索引、查询索引、删除索引

文章目录

  • MySQL
    • 5. 索引的实现
      • 5.1 B+ vs B
      • 5.2 聚簇索引 VS 非聚簇索引
    • 6. 索引操作
      • 6.1 创建主键索引
      • 6.2 创建唯一索引
      • 6.3 创建普通索引
      • 6.4 创建全文索引
      • 6.5 查询索引
      • 6.6 删除索引

MySQL

在这里插入图片描述

  

5. 索引的实现

  因为MySQL和磁盘交互的基本单位为Page(页)。

  MySQL 中要管理很多数据表文件,而要管理好这些文件,就需要 先描述,在组织 ,我们目前可以简单理解成一个个独立文件是有一个或者多个Page构成的。

   MySQL 会默认按照主键给我们的数据进行排序,从上面的Page内数据记录可以看出,数据是有序且彼此关联的。

在这里插入图片描述

  

  数据页与数据页之间通过指针连成双向链表。

  在页模式中,只有一个功能,就是在查询某条数据的时候直接将一整页的数据加载到内存中,以减少硬盘IO次数,从而提高性能。但是,我们也可以看到,现在的页模式内部,实际上是采用了链表的结构。

在这里插入图片描述

  

  但是多个Page彼此使用双链表链接起来,且每个Page内部的数据是基于链表的。那么,查找特定一条记录,也一定是线性查找,效率低。

  针对上面的单页Page,我们引入目录。

  此时给每个数据页建立起对应的目录,就是索引。

在这里插入图片描述
  

  在单表数据不断被插入的情况下, MySQL 会在容量不足的时候,自动开辟新的Page来保存新的数据,然后通过指针的方式,将所有的Page组织起来——给Page也带上目录。

  
在这里插入图片描述

  其实目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址。

  这个就是B+树。

  Page分为目录页和数据页。目录页只放各个下级Page的最小键值。

  查找的时候,自定向下找,只需要加载部分目录页到内存,即可完成算法的整个查找过程,大大减少了IO次数。

  

5.1 B+ vs B

  InnoDB 在建立索引结构管理数据时,其他数据结构不合适的原因如下:

  链表:线性遍历效率低。

  二叉搜索树:可能退化成为线性结构。

  AVL 和红黑树:虽是平衡或近似平衡的二叉结构,但相比多阶 B+树,树整体过高,导致系统与硬盘的 IO Page 交互更多。

  Hash:MySQL 支持但 InnoDB 和 MyISAM 不支持。Hash 算法虽有时查找快(O(1)),但范围查找不行。

  B 树:非叶子节点也存储数据,这会导致在相同大小的磁盘页中,B 树能存储的索引项比 B+ 树少。从而使得 B 树的阶数相对较低,树的高度可能更高,增加了磁盘 I/O 操作的次数。

  B+ 树:非叶子节点只存储索引信息,磁盘页能容纳更多的索引项,进一步降低了树的高度,减少了 I/O 次数,提高了查询性能。

  
数据结构演示
  

B树:
在这里插入图片描述
  

B+树:

在这里插入图片描述

  

5.2 聚簇索引 VS 非聚簇索引

  MyISAM 这种用户数据与索引数据分离的索引方案,叫做非聚簇索引。

  MyISAM 引擎同样使用B+树作为索引结果,叶节点的data域存放的是数据记录的地址。

  其中, MyISAM 最大的特点是,将索引Page和数据Page分离,也就是叶子节点没有数据,只有对应数据的地址。

  

mysql> create table mtest(-> id int primary key,-> name varchar(11) not null-> )engine=MyISAM;

  
在这里插入图片描述
  

在这里插入图片描述

  

  而InnoDB 是将索引和数据放在一起的。

  所以,InnoDB 这种用户数据与索引数据在一起索引方案,叫做聚簇索引。

  当然, MySQL 除了默认会建立主键索引外,我们用户也有可能建立按照其他列信息建立的索引,一般这种索引可以叫做辅助(普通)索引。

  对于 MyISAM ,建立辅助(普通)索引和主键索引没有差别,无非就是主键不能重复,而非主键可重复。

  

mysql> create table itest(-> id int primary key,-> name varchar(11) not null-> )engine=InnoDB;

  
在这里插入图片描述

  
在这里插入图片描述

  

6. 索引操作

6.1 创建主键索引

  (1)在创建表的时候,直接在字段名后指定 primary key。

create table user1(id int primary key, name varchar(30));

  

  (2)在创建表的最后,指定某列或某几列为主键索引。

create table user2(id int, name varchar(30), primary key(id));

  

  (3)创建表以后再添加主键。

create table user3(id int, name varchar(30));alter table user3 add primary key(id);

  

  主键索引的特点:

  一个表中,最多有一个主键索引,当然可以使符合主键。

  主键索引的效率高(主键不可重复)。

  创建主键索引的列,它的值不能为null,且不能重复。

  主键索引的列基本上是int。

  

6.2 创建唯一索引

  (1)在表定义时,在某列后直接指定unique唯一属性。

create table user4(id int primary key, name varchar(30) unique);

  

  (2)创建表时,在表的后面指定某列或某几列为unique

create table user5(id int primary key, name varchar(30), unique(name));

  
  (3)创建表以后再添加。

create table user6(id int primary key, name varchar(30));
alter table user6 add unique(name);

  

  唯一索引的特点:

  一个表中,可以有多个唯一索引。

  查询效率高。

  如果在某一列建立唯一索引,必须保证这列不能有重复数据。

  如果一个唯一索引上指定not null,等价于主键索引。

  

6.3 创建普通索引

  (1)在表的定义最后,指定某列为索引。

create table user8(id int primary key,
name varchar(20),
email varchar(30),
index(name) 
);

  

  (2)创建完表以后指定某列为普通索引。

create table user9(id int primary key, name varchar(20), email
varchar(30));
alter table user9 add index(name); 

  

  (3)创建一个索引名为 idx_name 的索引。

create table user10(id int primary key, name varchar(20), email
varchar(30));
create index idx_name on user10(name);

  

  普通索引的特点:

  一个表中可以有多个普通索引,普通索引在实际开发中用的比较多。

  如果某列需要创建索引,但是该列有重复的值,那么我们就应该使用普通索引。

  

6.4 创建全文索引

  当对文章字段或有大量文字的字段进行检索时,会使用到全文索引。MySQL提供全文索引机制,但是有要求,要求表的存储引擎必须是MyISAM,而且默认的全文索引支持英文,不支持中文。如果对中文进行全文检索,可以使用sphinx的中文版(coreseek)。

  如果使用如下查询方式,虽然查询出数据,但是没有使用到全文索引。

  
在这里插入图片描述

  可以用explain工具看一下,是否使用到索引。

   key为null表示没有用到索引。

  
在这里插入图片描述

  如何使用全文索引呢?
  
在这里插入图片描述

  

  通过explain来分析这个sql语句。
  
在这里插入图片描述

  

6.5 查询索引

  第一种方法: show keys from 表名;

  第二种方法: show index from 表名;

  第三种方法(信息比较简略): desc 表名;

  

6.6 删除索引

  第一种方法-删除主键索引: alter table 表名 drop primary key;

  

  第二种方法-其他索引的删除: alter table 表名 drop index 索引名; 索引名就是show keys from 表名中的 Key_name 字段

mysql> alter table user10 drop index idx_name;

  

  第三种方法方法: drop index 索引名 on 表名

mysql> drop index name on user8

  

  索引创建原则:

  比较频繁作为查询条件的字段应该创建索引。

  唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件。

  更新非常频繁的字段不适合作创建索引。

  不会出现在where子句中的字段不该创建索引。

  

其他概念:

  复合索引:

  复合索引是指基于多个列创建的索引。 例如,在一个表中有 col1、col2 和 col3 列,如果创建了一个复合索引 (col1, col2, col3),那么在查询时可以利用这个索引来提高查询效率。

  

  索引最左匹配原则:

  这是指在使用复合索引进行查询时,必须从索引的最左侧开始匹配。 例如,如果复合索引是 (col1, col2, col3) ,那么查询条件中只有以 col1 开头,或者以 col1 和 col2 开头,或者以 col1、col2 和 col3 开头的查询才能使用到这个复合索引。

  例如,如果有查询语句 WHERE col1 = 1 AND col2 = 2 或者 WHERE col1 = 1 可以使用该复合索引,但 WHERE col2 = 2 则无法使用。

  

  索引覆盖:

  索引覆盖是指查询所需的所有列的数据都可以从索引中直接获取,无需回表查询数据行。

  例如,如果有一个索引 (col1, col2) ,并且查询语句只是 SELECT col1, col2 FROM table ,那么就实现了索引覆盖,因为所需的列都在索引中可以直接获取,不需要再根据索引找到数据行获取其他列的值。 这样可以大大提高查询效率。

            

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

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

相关文章

C# 串口通信(通过serialPort控件发送及接收数据)

连接串口 界面设计打开串口发送数据通过文件发送发送数据 接收数据 首先可以在 工具箱中搜索serialport,将控件拖到你的Winfrom窗口。 界面设计 打开串口 private void Connect_Click(object sender, EventArgs e){serialPort1.PortName comboBox2.Text;//端口名s…

CAS单点登录

1.相同顶级域名的单点登录SSO 相同顶级域名的单点登录:SSO:SINGLE SIGN ON 单点登录可以通过基于用户会话的共享;分为两种,第一种:相同顶级域名; 原理是分布式会话完成的;关键是顶级域名的cookie值是可以共享的 比如…

【C#】ThreadPool的使用

1.Thread的使用 Thread的使用参考:【C#】Thread的使用 2.ThreadPool的使用 .NET Framework 和 .NET Core 提供了 System.Threading.ThreadPool 类来帮助开发者以一种高效的方式管理线程。ThreadPool 是一个线程池,它能够根据需要动态地分配和回收线程…

【Kubernetes】Deployment 的清理策略

Deployment 的清理策略 在 Deployment 中配置 spec.revisionHistoryLimit 字段,可以指定其 清理策略。该字段用于指定 Deployment 保留旧 ReplicaSet 的个数,即更新 Pod 前的版本个数。该字段的默认值是 10。 创建 revisionhistory-demo.yaml 文件&…

上升探索WebKit的奥秘:打造高效、兼容的现代网页应用

嘿,朋友们!想象一下,你正在浏览一个超级炫酷的网站,页面加载飞快,布局完美适应你的设备,动画流畅得就像你在看一场好莱坞大片。这一切的背后,有一个神秘的英雄——WebKit。今天,我们…

学习笔记--算法(双指针)3

快乐数 . - 力扣(LeetCode) 题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无…

如何在IDEA上使用JDBC编程【保姆级教程】

目录 前言 什么是JDBC编程 本质 使用JDBC编程的优势 JDBC流程 如何在IEDA上使用JDBC JDBC编程 1.创建并初始化数据源 2.与数据库服务器建立连接 3.创建PreparedStatement对象编写sql语句 4.执行SQL语句并处理结果集 executeUpdate executeQuery 5.释放资源 前言 在…

二叉树中的深搜

目录 二叉树中的深搜: 一、计算布尔二叉树的值 1.题目链接:2331. 计算布尔二叉树的值 2.题目描述: 3.解法(递归) 🍒算法思路: 🍒算法流程: 🍒算法代码…

C# Unity 面向对象补全计划 泛型

本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正 1.什么是泛型 泛型(Generics)是C#中的一个强大特性,允许你编写可以适用于多种数据类型的可重用代码,而不需要重复编写…

CSP-J复赛-模拟题4

1.区间覆盖问题: 题目描述 给定一个长度为n的序列1,2,...,a1​,a2​,...,an​。你可以对该序列执行区间覆盖操作,即将区间[l,r]中的数字,1,...,al​,al1​,...,ar​全部修改成同一个数字。 现在有T次操作,每次操作由l,r,p,k四个值组成&am…

GD32 SPI 通信协议

1.0 SPI 简介 SPI是一种串行通信接口,相对于IIC而言SPI需要的信号线的个数多一点,时钟的信号是主机产生的。 MOSI:主机发送,从机接收 MISO:主机接收,从机发送 CS:表示的是片选信号 都是单向…

C# Unity 面向对象补全计划 泛型约束

本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正 1.泛型约束了什么 在C#中,泛型约束用于限制泛型类型参数的类型 可以在泛型类型或方法的声明中使用 where 关键字来指定这些约束 2.约束栗子 基类约束…

LearnOpenGL-入门章节学习笔记

LearnOpenGL-入门章节学习笔记 简介一、核心模式与立即渲染模式二、扩展三、状态机四、对象 创建窗口一、Main函数——实例化窗口二、Callback Function 回调函数三、processInput 函数 创建三角形一、顶点输入二、顶点着色器三、编译着色器四、片段着色器五、着色器程序六、链…

【原创】下载RealEstate10K数据集原始视频的方法

前言:目前互联网上能搜到下载RealEstate10K数据集原始视频的方法都已经不能用了,这篇博客介绍一种目前可用的下载RealEstate10K数据集原始视频的方法,并给出自动化的脚本代码。 目录 RealEstate10K简介 RealEstate10K标注文本下载 RealEstate10K原始视频下载 环境安装 …

全面提升PDF编辑效率,2024年五大顶级PDF编辑器推荐!

在这个数字化飞速发展的时代,PDF文件已经成为我们日常工作和学习中不可或缺的一部分。然而,面对PDF文件的编辑和管理,许多人仍然感到困惑和无助。今天,就让我们一起探索几款高效、易用的PDF编辑器,它们将彻底改变你的工…

萱仔环境记录——git的安装流程

最近由于我有一个大模型的offer,由于我只在实验室的电脑上装了git,我准备在自己的笔记本上本地安装一个git,也给我的一个师弟讲解一下git安装和使用的过程,给我的环境安装章节添砖加瓦。 github是基于git的一个仓库托管平台。 g…

前端的学习-CSS(二)-弹性盒子-flex

一:子元素的属性 order:项目的排列顺序,数值越小,排列越靠前,默认为0。 flex-grow:定义项目的放大比例,默认为 0 ,即如果存在剩余空间,也不放大。 flex-shrink&#xff1…

鸿蒙应用服务开发【华为账号服务】

Account Kit 介绍 本示例展示了使用Account Kit提供的登录、授权头像昵称、实时验证手机号、收货地址、发票抬头、未成年人模式的能力。 本示例模拟了在应用里,调用一键登录Button组件拉起符合华为规范的登录页面;调用获取头像昵称接口获取头像昵称&a…

excel中有些以文本格式存储的数值如何批量转换为数字

一、背景 1.1 文本格式存储的数值特点 在平时工作中有时候会从别地方导出来表格,表格中有些数值是以文本格式存储的(特点:单元格的左上角有个绿色的小标)。 1.2 文本格式存储的数值在排序时不符合预期 当我们需要进行排序的时候…

IDEA全局搜索Jar包中内容

IDEA全局搜索Jar包中内容 【一】下载源码【二】搜索内容【1】按文件名搜索【2】全局关键字搜索【3】方法引用 【一】下载源码 想要搜索Jar中关键字,必须先把jar包源码下载下来,否则搜不到。 Preferences --> Maven --> Importing,根据…