MySQL_8 相当牛逼的索引机制

news2024/11/29 6:36:54

目录

一、索引机制的引入

        1.索引机制🐂B在哪里?

        2.索引机制提高查询速度的原理 : 

二、索引的创建

        1.索引分类 : 

        2.使用格式 : 

        3.代码演示 : 

三、索引的删除

        1.格式 : 

        2.演示 : 

四、索引的查询

        1.格式 : 

        2.演示 : 

五、索引的使用规则


一、索引机制的引入

        1.索引机制🐂B在哪里?

                我们先来创建一张学生表,向表中随意添加一些数据后,利用蠕虫复制(自我复制)将表中的数据量扩展到百万级别,代码如下 : 

CREATE TABLE IF NOT EXISTS `students`(
		`s_id` MEDIUMINT UNSIGNED NOT NULL,
		`s_name` VARCHAR(64) NOT NULL DEFAULT '',
		`s_age` SMALLINT UNSIGNED NOT NULL DEFAULT 0
) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin ENGINE INNODB;

INSERT INTO students
		VALUES
		(1, 'sdads', 22),
		(1, 'Cyan', 22),
		(3, 'Raln', 22),
		(1, 'sdads', 22),
		(122, 'sdads', 22),
		(9, 'sdads', 22),
		(1, 'NXOl', 22),
		(34, 'DANz', 22),
		(76, 'AMqwc', 22);
		

INSERT INTO students
		SELECT * FROM students;

                经过几轮蠕虫复制后,我们可以利用COUNT函数来查询表中现在一共有多少条记录,如下 : 

SELECT COUNT(*) FROM students;

                可以看到,表中现在已经有900多万条数据了,这么大的数据量,在查询数据时需要消耗多长的时间捏🤔 。我们来测试一下 : 
                先向表中另外添加一条要查询的数据(避开蠕虫复制的id),然后进行查询,如下 : 

INSERT INTO students
		VALUES
		(233, 'Ice', 21);

SELECT * 
		FROM students
		WHERE s_id = 233;

                在无索引机制的情况下,通过id查询数据用了足足4s多,你可以想象下面的场景——月黑风高夜,夜深人静时,你正想趁着此般时机在某网站上大饱眼福,就比如说在CSDN上吧,你想要让无穷无尽的知识映入你的眼帘,但是你发现,你每用鼠标点击一次都得等待4s多才能给你反馈,反复多次以后,你想骂娘了,***流量都准备好了给我整这玩意儿?
                没错,如果没有索引机制的加持,当数据量足够大时,比如达到百万级别以上,浏览网站将会是非常痛苦的一件事。那这时候可能就要有p小将(Personable小将,指风度翩翩的人)出来bb问了——你™BB一大堆说了个啥?索引机制呢?这踏🐎不是跑题水博文?
                p哥教训的是😭。这就来演示一下——如果我们用了索引机制,在相同的查询条件下,会用多长的时间。但是,演示之前我们先来看一下,目前900多万条的数据占了多大的空间,如下 : (ibd后缀,表示文件为INNODB存储引擎下保存的表数据和索引的文件)。

                为s_id字段创建索引(创建索引也需要时间),并进行相同的查询,如下 : 

CREATE INDEX id_index ON students(s_id);
SELECT * 
		FROM students
		WHERE s_id = 233;

                发现没有,相同的查询语句,添加索引前后的时间之比 = 4.269 / 0.019 ≈ 225,上百倍的性能差距。那么,我们再来看一下建立索引机制后,该表的数据发生了什么变化? 如下 : 

                可以发现,索引机制的本质,其实就是——以空间换时间,即索引本身的建立也是需要占用空间的。 

        2.索引机制提高查询速度的原理 : 

                以往常规的查询中,不管你查询什么数据,它都是从表头第一条记录开始查找,一直找到表的末尾,即扫描了全表。比方说你要查询一条id = 100的记录,就算在表中找到了一条id = 100的记录,但是仍然不能保证该记录下方的记录中没有id = 100的,因此,就算表中真的只有一条id = 100的记录,最终还是扫描了全表。
                那么在表数据量庞大的情况下,全表扫描带来的弊端是相当明显的,我们方才也看到了,查询一次都得4s以上,甲方不得喷死你?

                那么索引机制又是如何解决这个问题的呢?
                索引机制会根据定义索引的字段建立一个索引的数据结构,这个数据结构可能是二叉树,B+树等等。比方说,我们上文中对s_id字段建立了索引,那么以最简单的二叉树为例,如下图所示 : 

                采用“折半”的思想,取中位数为根结点,左子树的结点一定都比根结点小,右子树的结点一定都比根结点大。 那么,当我们要查询id = 233的学生时,只需要先和122判断,233比122大,直接就去122的右子树查询了,122的左子树一个都不需要比较,就大大减少了查询的次数,进而缩短了查询时间,提高了查询性能。
                但是,俗话说的好——甘瓜苦蒂,天下物无全美!
                索引机制也存在自己的缺点——
                首先最直观的一点,由于索引采用了“以空间换时间”的思想,所以建立索引一定会增大对空间的开销
                其次,对于所引建立的数据结构,若表中数据出现了诸如"增加,删除,更改"这些DML(Data Manipulation Language) 时,就需要对这个数据结构进行维护,影响了DML的执行效率

                实际上,两害取其轻,由于在日常的项目开发和维护中,DQL(Data Query Language) 的使用频率远远高过DML,两者的使用频率之比接近9 : 1;因此,我们往往还是乐于去建立索引,以极大提高查询语句的性能,毕竟21世纪,时间才是最珍贵嘛😋。


二、索引的创建

        1.索引分类 : 

        主键索引:当表中定义了主键(PRIMARY KEY)时,主键自动为主索引,可以说,主键是一个特殊的索引,有主键限制的查询语句,查询速度会很快。

        唯一索引:当表中定义了UNIQUE约束时,自动建立唯一索引(也可以手动创建),有UNIQUE限制的查询语句,查询速度也很快。

        普通索引:就是INDEX;虽然普通,但使用频率却是最高的,因为更加灵活;普通索引允许数据重复,比如说name字段。

        全文索引:FULLTEXT;适用于MyISAM存储引擎。PS :由于MySQL自带的全文索引比较LOW,没法用,因此实际开发中使用最多的是Solr和ElasticSearch(ES)

        2.使用格式 : 

        1° 创建唯一索引 : 

        CREATE UNIQUE INDEX index_name ON table_name(field_name);

        创建普通索引 : 

        CREATE INDEX index_name ON table_name(field_name);

        ALTER TABLE table_name ADD INDEX index_name(field_name);

        创建主键索引 : 

        ALTER TABLE table_name ADD PRIMARY KEY (field_name);

        3.代码演示 : 

                建立一张动物表animals,令动物编号a_no为主键,动物名字a_name为UNIQUE,使用"SHOW INDEXES FROM table_name"指令来查看动物表的索引情况,代码如下 : 

CREATE TABLE IF NOT EXISTS `animals`(
		`a_no` MEDIUMINT UNSIGNED PRIMARY KEY,
		`a_name` VARCHAR(64) UNIQUE NOT NULL,
		`a_habitat` VARCHAR(64) NOT NULL DEFAULT ''
) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin ENGINE INNODB;

SHOW INDEXES FROM animals;

                可以看到,Non_unique均是0,表示主键索引和唯一索引均不允许数据重复;Column_name则表示当前索引添加在了哪个字段上。
                尝试通过手动添加的方式建立唯一索引,如下 : 

CREATE UNIQUE INDEX a_nameIndex ON animals(a_name);
CREATE UNIQUE INDEX a_nameIndex2 ON animals(a_name);

SHOW INDEXES FROM animals;

                可见,MySQL允许在同一字段上创建名称不同的多个索引;当然,主键索引除外,每张表最多只允许存在一个主键。
                下面我们另建一张表,演示一下手动创建主键,以及普通索引的创建,代码如下 : 

CREATE TABLE IF NOT EXISTS `animals_EX`(
		`no` MEDIUMINT UNSIGNED,
		`name` VARCHAR(64) UNIQUE NOT NULL,
		`habitat` VARCHAR(64) NOT NULL DEFAULT ''
) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin ENGINE INNODB;
# 手动添加主键
ALTER TABLE `animals_EX` ADD PRIMARY KEY(`no`);

# 手动添加普通索引
ALTER TABLE `animals_EX` ADD INDEX index_nameTest(`name`);
CREATE INDEX `index_nameTest2` ON animals_EX(`name`);
CREATE INDEX `index_habitatTest` ON animals_EX(habitat);

# 查看表的索引信息
SHOW INDEXES FROM animals_EX;

                可以看到,普通索引的Non_unique栏下是1,也就是允许有重复数据。


三、索引的删除

        1.格式 : 

        删除非主键索引 : 

        DROP INDEX index_name ON table_name;

        删除主键索引 : 

        ALTER TABLE table_name DROP PRIMARY KEY;

        PS : 

        若想修改索引——删除当前索引;添加新的索引

        2.演示 : 

                对于上文创建的animals_EX表的索引,如下图所示 : 

                要求删除该表的所有索引,如下 : 

# 删除主键索引
ALTER TABLE `animals_EX` DROP PRIMARY KEY;

# 删除非主键索引
DROP INDEX `name` ON `animals_EX`;
DROP INDEX index_nameTest ON animals_EX;
DROP INDEX index_nameTest2 ON animals_EX;
DROP INDEX index_habitatTest ON animals_EX;

SHOW INDEXES FROM animals_EX;


四、索引的查询

        1.格式 : 

        SHOW INDEX FROM table_name;

        SHOW INDEXES FROM table_name;

        SHOW KEYS FROM table_name;

        DESC table_name; (不如前三种方式的信息详细)

        2.演示 : 

                以动物表animals为例,查询其索引的定义情况。
                注意,前三种方式得到的结果是一模一样的

SHOW INDEX FROM animals;
SHOW INDEXES FROM animals;
SHOW KEYS FROM animals;

                第四种方式DESC table_name,本质上就是查看表的结构,不过也可以看出一些关于索引的信息。如下 : 

DESC animals;


五、索引的使用规则

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

        eg : SELECT * FROM emp WHERE eno = 100; (雇员编号)

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

        eg : SELECT * FROM emp WHERE esex = 'male'; (性别往往非男即女,存在大量重复数据)

        更新较为频繁的字段不适合建立索引

        eg : SELECT * FROM emp WHERE attendance_times; (若字段频繁更新,就需要对该字段索引的数据结构进行频繁的维护,会消耗较多性能,维护代价高)。

        不会出现在WHERE子句中的字段不适合创建索引。(用不上)

        System.out.println("END------------------------------------------------------------------------------"); 

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

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

相关文章

Linux---强制停止、退出登出、history、yum

1. ctrl c 强制停止 Linux某些程序的运行,如果想要强制停止它,可以使用快捷键ctrl c: [shaonianlocalhost ~]$ tail ^C [shaonianlocalhost ~]$ 命令输入错误,也可以通过快捷键ctrl c,退出当前输入,重…

如何在 Alpine Linux 上启用或禁用防火墙?

防火墙是计算机网络安全的重要组成部分,它用于保护计算机和网络免受未经授权的访问和恶意攻击。Alpine Linux 是一种轻量级的 Linux 发行版,常用于构建容器化应用和嵌入式系统。本文将详细介绍如何在 Alpine Linux 上启用或禁用防火墙。步骤 1&#xff1…

MySQL复习

文章目录 1、操作数据库1.1、操作数据库1.2、数据库的数据类型1.3、数据库的字段属性1.4、创建数据表1.5、MyISAM和InnoDB1.6、修改删除表 2、MySQL数据管理2.1、外键2.2、DML语言(全部记住)2.3、添加2.4、修改2.5、删除 3、DQL查询数据3.1、DQL3.2、查询…

EMPIRE: LUPINONE实战演练

文章目录 EMPIRE: LUPINONE实战演练一、前期准备1、相关信息 二、信息收集1、端口扫描2、访问网站3、查看源码4、dirsearch扫描目录5、访问robots文件6、访问myfiles文件7、模糊测试8、访问秘密文件9、查找秘钥10、查看秘钥11、解码12、解密13、远程连接 三、提权1、查找flag2、…

Unity---委托与事件

目录 1.委托和事件在使用上的区别是什么? 2. delegate委托 2.1示意图 2.2 DelegetTest.cs 2.3 Deleget_A.cs 2.4 Deleget_B.cs 2.5 运行unity. 点击按键 A 2.6 点击按键 B 3.Event 事件 3.1单个通知 3.1.1示意图 3.1.2 Event_Test.cs 3.1.3 Event_A.cs 3…

专家警告AI可能会导致人类灭绝

人工智能可能导致人类灭绝,包括 OpenAI 和 Google Deepmind 负责人在内的专家警告说 数十人支持在人工智能安全中心 的网页上发表的声明。 它写道:“减轻人工智能灭绝的风险应该与其他社会规模的风险(如流行病和核战争)一起成为全…

Spring(二)获取bean和依赖注入

一、获取bean的三种方式: 1.根据bean的id获取: Student studentOne (Student) ioc.getBean("studentOne"); 2.获取bean所需要的类型的class对象: Student student ioc.getBean(Student.class); 我们运行之后如下所示&#xff1…

为kong网关添加限流插件

限流用于控制发送到上游服务的请求速率。 它可用于防止 DoS 攻击、限制网络抓取和其他形式的过度使用。 如果没有速率限制,客户可以无限制地访问您的上游服务,这可能会对可用性产生负面影响。 一、全局范围内的限流 1、启用限流 [rootmin ~]# curl -i…

AI落地:儿童节贺卡

昨天有个朋友Lisa找到我,她是幼儿园的老师,看到我最近搞了个爱落地星球,在研究各行各业AI落地的事情,问我能不能用AI帮她写一百多张贺卡。 说起来写贺卡,我只会写“节日快乐”。现在有了ChatGPT,那就大不一…

十六、多线程(中)

文章目录 一、线程互斥(一)四个概念1.临界资源2.临界区3.互斥特性4.线程互斥5.原子性 二、互斥(一)在执行语句的任何地方,线程可能被切换走(二)切换会保存上下文(三)抢票…

用HTML、CSS和JavaScript实现鼠标可交互的3D太阳和月亮切换效果

部分数据来源:ChatGPT 引言 太阳和月亮对于我们来说是一种常见的对比,这篇文章将介绍一个使用HTML、CSS和JavaScript创建的网页场景,能够把太阳和月亮切换展示给用户。这个场景能够让用户使用鼠标和滚轮与场景互动,带来更多的趣…

解锁Qt QListWidget的全部潜力——用最佳实践和技巧赢得用户的喜爱和赞誉!

文章目录 前言一、属性和方法添加列表项获取当前选中的列表项删除列表项列表显示模式交替背景色 二、信号与槽选中的行数变化item被点击 三、解决icon图标模式下图标不对称的问题1、设置属性2、面向结果的手动换行 总结 前言 在现代的GUI应用程序中,列表框是必不可…

什么是千兆光模块和万兆光模块?它们有什么区别?

众所周知千兆光模块和万兆光模块的主区别在于它们的传输速率不一样,那你还知道千兆光模块和万兆光模块的其他区别吗?接下来海翎光电的小编将对千兆光模块和万兆光模块的区别进行详细解析。 什么是千兆光模块? 千兆光模块即传输速率为1000Mbps…

Java之路:构建坚实基础,系统学习Java技术的终极指南

无论是初学者还是有经验的专业人士,在学习一门新的IT技术时,都需要采取一种系统性的学习方法。作为一名Java技术er,下面我将介绍我是如何系统的学习Java技术的。 一、Java技术介绍 Java是一种广泛应用于软件开发的高级编程语言,…

数据链路层:点对点协议PPP

数据链路层:点对点协议PPP 笔记来源: 湖科大教书匠:点对点协议PPP 声明:该学习笔记来自湖科大教书匠,笔记仅做学习参考 数据链路层只负责直接相连的两个结点之间的通信 PPP是点对点数据链路层协议 用户通过ISP接入因特…

sklearn实现余弦相似度计算

from sklearn.metrics.pairwise import cosine_similarity cosine_similarity() 这个函数的输入是 n 个长度相同的 list 或 array 函数的处理是计算这 n 个 list 两两之间的余弦相似性 最后生成的是一个 n*n 的相似性矩阵s,s[i][j] 表示输入中第 i 个和第 j 个元…

如何在 Ubuntu Linux 上使用 SNAP 安装 Docker?

Docker 是一种开源的容器化平台,它允许开发人员将应用程序和其依赖项打包到一个可移植的容器中,以便在不同的环境中运行。在 Ubuntu Linux 上,我们可以使用 SNAP(一种软件包管理系统)来安装和管理 Docker。本文将详细介…

ProtoBuf 语法(一)

系列文章 ProtoBuf 语法(二) ProtoBuf 语法(三) 文章目录 前言一、字段规则二、消息类型的定义与使用2.1 定义2.2 使用 三、enum 类型3.1 定义规则3.2 注意事项 四、any 类型4.1 类型说明4.2 类型使用 五、oneof 类型六、map 类型…

HACKER KID: 1.0.1实战演练

文章目录 HACKER KID: 1.0.1实战演练一、前期准备1、相关信息 二、信息收集1、端口扫描2、访问网站3、扫描目录4、查看源码5、请求参数6、burpsuite批量请求7、编辑hosts文件8、DNS区域传输9、编辑hosts10、访问网站11、注册账号12、burpsuite抓包13、XML注入14、解密15、登录网…

供应链对于小程序、app等平台能带来什么好处?

供应链对于小程序、 app等平台的重要性不言而喻,这是一个企业生存的根本,只有保证了供应链,才能获得足够的产品和服务,保证企业能够长期稳定发展。因此很多企业都开始重视供应链,同时也在为之努力。 那么,…