MySQL 索引(下)

 🎉欢迎您来到我的MySQL基础复习专栏

☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹
✨博客主页:小小恶斯法克的博客
🎈该系列文章专栏:重拾MySQL-进阶篇
🍹文章作者技术和水平很有限,如果文中出现错误,希望大家能指正🙏
📜 感谢大家的关注! ❤️

目录

🚀索引分类

🚀聚集索引&二级索引

🚀索引语法


🚀引分类

在MySQL数据库将索引的具体类型主要分为以下几类主键索引唯一索引常规索引文索引

分类

关键字

针对于表中主键创建的索引,唯一标识表中的每一行数据

默认自动创建 , 只能有一个

不允许NULL值

PRIMARY KEY

唯一

避免同一个表中某数据列中的值重复,确保列中的值唯一

可以有多个NULL值
允许重复值,但不允许重复的索引值

UNIQUE

快速定位特定数据,提高查询性能

- 允许重复值和NULL值
- 适用于经常被搜索的列

INDEX

全文索引查找的是文本中的关键词而不是比较索引中的值

只能在MyISAM存储引擎上使用
适用于大量文本数据的搜索

FULLTEXT

🚀聚集索引&二级索引

在InnoDB存储引擎中,根据索引的存储形式又可以分为以下两种

分类

集索引 (Clustered

 

Index)

将数据存储与索引放到了一块索引结构的叶子 节点保存了行数据

须有 ,而且只 有一个

二级索引 (Secondary Index)

将数据与索引分开存储索引结构的叶子节点关 联的是对应的主键

可以存在多个

聚集索引选取规则 :

 ✨表中只能有一个聚集索引:每个表只能有一个聚集索引,该索引决定了数据在磁盘上的物理排序顺序。

✨主键作为默认的聚集索引:如果没有显式地指定聚集索引,MySQL将使用主键作为默认的聚集索引。主键是唯一标识表中每一行数据的列。(即如果存在主键,主键索引就是聚集索引。)

✨如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索 引。

✨唯一非空索引可以作为聚集索引:如果表中没有主键或者不想使用主键作为聚集索引,可以选择一个唯一非空索引作为聚集索引,这样可以提高查询性能并减少磁盘IO操作。

聚集索引的选择应考虑查询频率和范围:选择适合查询频率高且范围较小的列作为聚集索引,这样可以减少磁盘IO操作,并提高查询效率。

✨聚集索引的列顺序很重要:聚集索引的列顺序对查询性能有影响,通常情况下,将经常用于过滤和排序的列放在前面,以便优化查询性能。

✨避免频繁更新聚集索引列:由于聚集索引决定了数据在磁盘上的物理排序顺序,频繁更新聚集索引列可能导致数据重组和性能下降,因此,如果有大量更新操作,应该谨慎选择聚集索引。 

请注意,聚集索引只适用于使用InnoDB存储引擎的表。对于使用MyISAM存储引擎的表,可以通过显示指定ALTER TABLE语句来创建聚集索引。

 聚集索引和二级索引的具体结构如下:(以下分析以及图片来自于黑马的视频)  

聚集索引的叶子节点下挂的是这一列的数据 

二级索引的叶子节点下挂的是该字段值对应的主键值

接下来我们来分析一下当我们执行如下的SQL语句时具体的查找过程是什么样子的

具体过程如下 :

. 由于是根据name字段进行查询,所以先根据name='Arm'name字段的二级索引中进行匹配查找,但是在二级索引中只能查找到Arm对应的主键10

. 由于查询返回的数据是*,所以此时还需要根据主键值10聚集索引中查找10对应的记录终找到10对应的行row

. 最终拿到这一行的数据,直接返回即可。 

回表查询: 这种先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。

✨以下两条SQL语句,那个执行效率高? 为什么?

A. select * from user where id = 5 ;

B. select * from user where name = 'bob' ;

备注 : id为主键,  name字段创建的有索引;

解答

✨在这种情况下,执行效率高的SQL语句是A. select * from user where id = 5;。原因如下:

 ✨主键索引的查找效率高:由于id是主键,主键索引是一种特殊的索引,具有唯一性和快速查找的特点。通过主键索引可以直接定位到指定id的行,因此查询效率高。

✨因为A语句直接走聚集索引,直接返回数据。   

✨而B语句需要先查询name字段的二级索引,然后再查询聚集索引,也就是需要进行回表查询。 

 思考

InnoDB主键索引的B+tree高度为多高呢 ?

InnoDB主键索引的B+树的高度取决于数据表中的行数和索引的大小

B+树是一种常用的索引结构,用于在数据库中实现索引。对于InnoDB存储引擎而言,主键索引是基于B+树实现的。

B+树的高度是指从根节点到叶子节点的层数。在InnoDB中,B+树的高度通常较低,这是因为InnoDB采用了多级索引的技术。

  

假设 :

一行数据大小为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 左右的记录

🚀索引语法

创建索引

CREATE  [ UNIQUE | FULLTEXT ]  INDEX  index_name  ON  table_name  (
index_col_name,... ) ;

查看索引

SHOW  INDEX  FROM  table_name ;

删除索引

DROP  INDEX  index_name  ON  table_name ;

案例演示 :

create table tb_user (id int primary key auto_increment comment '主键 ',name varchar (50) not null comment '名字 ',phone varchar (11) not null comment '手机号码 ',email varchar (100) comment '邮箱 ',profession varchar (11) comment '专业 ',age tinyint unsigned comment '年龄 ',gender char (1) comment '性别 , 1: 男, 2: 女 ',status char (1) comment '状态 ',createtime datetime comment '创建时间 ') comment '用户表 ';INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'a ', '15377777770 ', 'lvbu666@163.com', '软件工程 ', 23, '1 ', '6 ', '2001-02-02 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'b ', '15377777771 ', 'caocao666@qq.com', '电气工程 ', 33, '1 ', '0 ', '2001-03-05 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'c ', '15377777772 ', '17799990@139.com', '计科 ', 34, '1 ', '2 ', '2002-03-02 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'd ', '15377777773 ', '17799990@sina.com', '工程造价 ', 54, '1 ', '0 ', '2001-07-02 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'e ', '15377777774 ', '19980729@sina.com', '软件工程 ', 23, '2 ', '1 ', '2001-04-22 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'f ', '15377777775 ', 'daqiao666@sina.com', '药学 ', 22, '2 ', '0 ', '2001-02-07 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'g ', '15377777776 ', 'luna_love@sina.com', '应用数学 ', 24, '2 ', '0 ', '2001-02-08 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'h ', '17799990007 ', 'chengyaojin@163.com', '化工 ', 38, '1 ', '5 ', '2001-05-23 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'i ', '17799990008 ', 'xiaoyu666@qq.com', '金属材料 ', 43, '1 ', '0 ', '2001-09-18 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'j ', '17799990009 ', 'baiqi666@sina.com', '机械工程及其自动 化 ', 27, '1 ', '2 ', '2001-08-16 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'k ', '17799990010 ', 'hanxin520@163.com', '无机非金属材料工 程 ', 27, '1 ', '0 ', '2001-06-12 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'l ', '17799990011 ', 'jingke123@163.com', '会计 ', 29, '1 ', '0 ', '2001-05-11 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'n ', '17799990012 ', 'lanlinwang666@126.com', '工程造价 ', 44, '1 ', '1 ', '2001-04-09 00:00:00 ');
INSERT INTO tb_user (name, phone, email, profession, age, gender, status,
createtime) VALUES ( 'm ', '17799990013 ', 'kuangtie@sina.com', '应用数学 ', 43, '1 ', '2 ', '2001-04-10 00:00:00 ');

数据如下:

  

 完成下列需求:

name字段为姓名字段该字段的值可能会重复为该字段创建索引

CREATE INDEX idx_user_name ON tb_user (name);

 

如果name字段的值可能会重复,可以使用普通索引来提高查询效率。可以使用以下SQL语句为name字段创建普通索引:

ALTER TABLE tb_user ADD INDEX idx_name (name);

这条语句使用了ALTER TABLE命令,用于修改表结构。ADD INDEX表示要添加一个普通索引,idx_name是索引的名称,name是要创建索引的字段名。

执行这条语句后,MySQL会为name字段创建一个普通索引,可以提高对该字段的查询效率。当查询条件中包含name字段时,MySQL可以使用该索引进行快速查询。需要注意的是,如果name字段的值经常被更新,那么维护索引的代价可能会比较高,因此需要根据实际情况来选择是否创建索引。

phone手机号字段的值是非空且唯一的为该字段创建唯一索引

create index idx_user_phone on tb_user (phone);
ALTER TABLE tb_user ADD UNIQUE INDEX idx_phone (phone);

 这条语句使用了ALTER TABLE命令,用于修改表结构。ADD UNIQUE INDEX表示要添加一个唯一索引,idx_phone是索引的名称,phone是要创建唯一索引的字段名。

执行这条语句后,MySQL会为phone字段创建一个唯一索引,确保该字段的值非空且唯一。如果插入重复的phone值,MySQL会抛出错误提示。

profession  age  status创建联合索引。

CREATE INDEX idx_profession_age_status ON tb_user (profession, age, status);
ALTER TABLE tb_user ADD INDEX idx_profession_age_status (profession, age, status);

这条语句使用了ALTER TABLE命令,用于修改表结构。ADD INDEX表示要添加一个普通索引,idx_profession_age_status是索引的名称,profession、age、status是要创建联合索引的字段名。

执行这条语句后,MySQL会为profession、age、status字段创建一个联合索引,可以提高这三个字段的查询效率。当查询条件中包含这三个字段中的任意一个或多个时,MySQL可以使用该联合索引进行快速查询。

为email建立合适的索引来提升查询效率

CREATE INDEX idx_email ON tb_user (email);

 

为了提高email字段的查询效率,可以根据实际情况选择创建普通索引或全文索引。

如果查询条件中只包含email字段,可以使用普通索引。可以使用以下SQL语句为email字段创建普通索引:

ALTER TABLE tb_user ADD INDEX idx_email (email);

这条语句使用了ALTER TABLE命令,用于修改表结构。ADD INDEX表示要添加一个普通索引,idx_email是索引的名称,email是要创建索引的字段名。

如果查询条件中包含email字段的全文搜索,可以使用全文索引。可以使用以下SQL语句为email字段创建全文索引:

ALTER TABLE tb_user ADD FULLTEXT INDEX idx_email (email);

这条语句使用了ALTER TABLE命令,用于修改表结构。ADD FULLTEXT INDEX表示要添加一个全文索引,idx_email是索引的名称,email是要创建索引的字段名。

需要注意的是,全文索引只能用于全文搜索,不能用于普通的等值查询。因此,如果查询条件中只包含email字段的等值查询,应该使用普通索引。

完成上述的需求之后,我们再查看tb_user表的所有的索引数据

show index from tb_user;

执行:

  


今天的学习就到这里,希望对你有帮助! 

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

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

相关文章

推荐新版AI智能聊天系统网站源码ChatGPT NineAi

Nine AI.ChatGPT是基于ChatGPT开发的一个人工智能技术驱动的自然语言处理工具,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写邮件、视频脚本、文案、翻译、代…

GoZero微服务个人探究之路(七)添加中间件、自定义中间件

说在前面 官方已经自己实现了很多中间件,我们可以方便的直接使用,不用重复造轮子了 开启方式可以看官方文档 中间件 | go-zero Documentation 实现自定义的中间件 在业务逻辑中,我们需要实现自定义功能的中间件 ------这里我们以实现跨源…

Spring+SprinMVC+MyBatis配置方式简易模板

SpringSprinMVCMyBatis配置方式简易模板代码Demo GitHub访问 ssm-tpl-cfg 一、SQL数据准备 创建数据库test,执行下方SQL创建表ssm-tpl-cfg /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Versio…

Linux ---- 小玩具

目录 一、安装: 1、佛祖保佑,永不宕机,永无bug 2、小火车 3、艺术字和其它 天气预报 艺术字 4、会说话的小牦牛 5、其他趣味图片 我爱你 腻害 英雄联盟 帅 忍 龙 你是猪 福 好运连连 欢迎 加油 想你 忘不了你 我错了 你…

细说JavaScript事件处理(JavaScript事件处理详解)

js语言的一个特色和就是它的动态性,即一时间驱动的方式对用户输入作出反应而不需要依赖服务器端程序。事件是指人机交互的结果,如鼠标移动、点击按钮、在表单中输入数据或载入新的Web洁面等。 一、什么是事件 1、事件类型 1.1、事件源 1.2、事件处理…

Node.js Stream.pipeline() Method

Why Stream.pipeline 通过流我们可以将一大块数据拆分为一小部分一点一点的流动起来,而无需一次性全部读入,在 Linux 下我们可以通过 | 符号实现,类似的在 Nodejs 的 Stream 模块中同样也为我们提供了 pipe() 方法来实现。 未使用 Stream p…

Pyro —— Understanding how pyro works

目录 Simulation fields Inside the Pyro Solver Colliders Pressure projection Simulation fields Pyro是纯体积流体解算器,表示流体状态的数据存于各种标量场和矢量场;Smoke Object会创建这些场,且能可视化这些场; vel场&…

【JavaEE】网络原理:网络中的一些基本概念

目录 1. 网络通信基础 1.1 IP地址 1.2 端口号 1.3 认识协议 1.4 五元组 1.5 协议分层 什么是协议分层 分层的作用 OSI七层模型 TCP/IP五层(或四层)模型 网络设备所在分层 网络分层对应 封装和分用 1. 网络通信基础 1.1 IP地址 概念:IP地址…

C语言/c++指针详细讲解【超详细】【由浅入深】

指针用法简单介绍 指针,是内存单元的编号。 内存条分好多好多小单元,一个小单元有 8 位,可以存放 8 个 0 或 1;也就是说,内存的编号不是以位算的,而是以字节算的,不是一个 0 或 1 是一个编号&…

立体视觉几何(一)

1.什么是立体视觉几何 立体视觉对应重建: • 对应:给定一幅图像中的点pl,找到另一幅图像中的对应点pr。 • 重建:给定对应关系(pl, pr),计算空间中相应点的3D 坐标P。 立体视觉:从图像中的投影恢复场景中点…

list下

文章目录 注意:const迭代器怎么写?运用场合? inserterase析构函数赋值和拷贝构造区别?拷贝构造不能写那个swap,为什么?拷贝构造代码 面试问题什么是迭代器失效?vector、list的区别? 完整代码 注…

qt学习:QT对话框+颜色+文件+字体+输入

目录 概述 继承图 QColorDialog 颜色对话框 QFileDialog 文件对话框 保存文件对话框 QFontDialog 字体对话框 QInputDialog 输入对话框 概述 对于对话框的功能,在GUI图形界面开发过程,使用是非常多,那么Qt也提供了丰富的对话框类QDia…

网络:FTP

1. FTP 文件传输协议,FTP是用来传输文件的协议。使用FTP实现远程文件传输的同时,还可以保证数据传输的可靠性和高效性。 2. 特点 明文传输。 作用:可以从服务器上下载文件,或将本地文件上传到服务器。 3. FTP原理 FTP有控制层面…

坦克大战游戏代码

坦克大战游戏 主函数战场面板开始界面坦克父类敌方坦克我方坦克子弹爆炸效果数据存盘及恢复图片 主函数 package cn.wenxiao.release9;import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing.JFrame; import javax.swing.JMenu; impor…

RS-485通讯

RS-485通讯协议简介 与CAN类似,RS-485是一种工业控制环境中常用的通讯协议,它具有抗干扰能力强、传输距离远的特点。RS-485通讯协议由RS-232协议改进而来,协议层不变,只是改进了物理层,因而保留了串口通讯协议应用简单…

【HarmonyOS】掌握布局组件,提升应用体验

从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是…

【RT-DETR有效改进】华为 | GhostnetV2移动端的特征提取网络效果完爆MobileNet系列

前言 大家好,这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进,内容持续更新,每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本,同时修改内容也支持ResNet32、ResNet101和PP…

自动控制原理——数学模型建立

目标 1.数学模型概念 描述系统输入、输出变量以及内部个变量之间的关系的数学表达式 2.建模方法 解析法(机理解析法): 根据系统工作所依据的物理定律写运动方程 实验法(系统辨识法): 给系统施加某种测试信号&am…

万户 ezOFFICE wf_process_attrelate_aiframe.jsp SQL注入漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

Intel开发环境Quartus、Eclipse与WSL的安装

PC :win10 64bit 安装顺序:先安装Quartus 21.4,接着Eclipse或者WSL(Windows Subsystem for Linux),Eclipse与WSL的安装不分先后。 为什么要安装Eclipse? 因为Eclipse可以开发基于Nios II的C/…