【MYSQL】索引机制概述

 由于MySQL是作为存储层部署在业务系统的最后端,所有的业务数据最终都要入库落盘,但随着一个项目在线上运行的时间越来越久,数据库中的数据量自然会越来越多,而数据体积出现增长后,当需要从表查询一些数据时,效率会越发低下。在正常情况下,表的查询性能和数据量是成反比的,也就是数据越多,查询越慢。

这是什么原因导致的呢?由于MySQL默认的查询方式导致的,举个例子~

SELECT * FROM `zz_student`;
+------------+--------+------+--------+
| student_id | name   | sex  | height |
+------------+--------+------+--------+
|          1 | 竹子   | 男   | 185cm  |
|          2 | 熊猫   | 女   | 170cm  |
|          3 | 子竹   | 男   | 182cm  |
|          4 | 棕熊   | 男   | 187cm  |
|          5 | 黑豹   | 男   | 177cm  |
|          6 | 脑斧   | 男   | 178cm  |
|          7 | 兔纸   | 女   | 165cm  |
+------------+--------+------+--------+

SELECT * FROM `zz_student`  WHERE name = "脑斧";

上面给出了一张学生表,其中有七位学生信息,而此时要查询姓名为「脑斧」的学生信息时,MySQL底层是如何检索数据的呢?会触发磁盘IO,对表中的数据进行逐条读取并判断,也就是说,在这里想要查找到符合要求的数据,至少要经过六次磁盘IO才能检索到目标(暂且先不考虑局部性读取原理与随机IO)。

  • 那假设这个表中有1000W条数据呢?要查的目标数据位于表的900W行以后怎么办?岂不是要触发几百万次磁盘IO才能检索到数据啊,如果真的这样去干,其效率大家可想而知。

在这种情况下,又该如何去提升数据库的查询性能呢?因为查询往往都是一个业务系统中最频繁的操作,一般项目的写/读请求比例都遵循三七定律,也就是30%的请求会涉及到写库操作,另外70%则属于查库类型的操作。

   在思考如何提升查询性能前,咱们不妨先回想一下小时候的场景,小时候由于刚接触汉字,很多字都不认识,所以通常每个人小时候都会拥有一本「新华字典」,但一本字典那么厚,我们是一页页去翻的吗?并不是,字典中有目录索引,我们可以根据音节、偏旁等方式查找不认识的字。

在「新华字典」中一页页翻找某个汉字,就类似于我们前面给出的全表扫描方式,效率特别特别低,而通过目录索引则能够在很短的时间内找到目标汉字。

   既然字典中都存在目录索引页,能帮助小时候的我们快速检索汉字,那这个思想能否应用到数据库中来呢?答案是当然可以,并且MySQL也提供了索引机制,索引是数据库中的核心组件之一,一张表中建立了合适的索引后,往往在面对海量数据查询时,能够事半功倍,接下来一起聊一聊MySQL的索引。

索引机制会分为上、中、下三篇进行阐述,大致内容如下:
《上篇:索引初识篇》主要讲解索引的概述、分类、使用与管理等;
《中篇:索引应用篇》主要阐述索引优劣分析、建立索引的原则、索引失效的场景、如何正确的使用索引、索引优化机制等;
《下篇:索引原理篇》则主要讲述索引的底层实现、B+Tree、Hash数据结构、聚簇索引和非聚簇索引实现、索引查询原理、索引管理实现等;

一、MySQL索引机制概述

   对于MySQL索引机制的作用,经过上述「新华字典」的案例后可得知:索引就是用来帮助表快速检索目标数据的。此时先来简单回顾一下MySQL中索引是如何使用的呢?首先需要创建索引,MySQL可以通过CREATE、ALTER、DDL三种方式创建一个索引。

1.1、MySQL索引的创建方式

  • ①使用CREATE语句创建

CREATE INDEX indexName ON tableName (columnName(length) [ASC|DESC]);

这种创建方式可以给一张已存在的表结构添加索引,其中需要指定几个值:

  • indexName:当前创建的索引,创建成功后叫啥名字。
  • tableName:要在哪张表上创建一个索引,这里指定表名。
  • columnName:要为表中的哪个字段创建索引,这里指定字段名。
  • length:如果字段存储的值过长,选用值的前多少个字符创建索引。
  • ASC|DESC:指定索引的排序方式,ASC是升序,DESC是降序,默认ASC

当然,上述语句中的INDEX也可更改为KEY,作用都是创建一个普通索引,而对于其他的索引类型,这点在后续的索引分类中再聊。

  • ②使用ALTER语句创建
ALTER TABLE tableName ADD INDEX indexName(columnName(length) [ASC|DESC]);

这里的参数都相同,所以不再重复赘述。

  • ③建表时DDL语句中创建
CREATE TABLE tableName(  
  columnName1 INT(8) NOT NULL,   
  columnName2 ....,
  .....,
  INDEX [indexName] (columnName(length))  
);

这种方式就比较适合在库表设计时,已经确定了索引项的情况下建立。

1.2、查询、删除、指定索引

但不管通过哪种方式建立索引,本质上创建的索引都是相同的,当索引创建完成后,可通过SHOW INDEX FROM tableName;这条命令查询一个表中拥有的索引,如下:

 
CREATE TABLE `zz_user`  (
  `user_id` int(8) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) NULL DEFAULT "",
  `user_sex` varchar(255) NULL DEFAULT "",
  `user_phone` varchar(255) NULL DEFAULT "",
	PRIMARY KEY (`user_id`) USING BTREE
)
    ENGINE = InnoDB 
    CHARACTER SET = utf8 
    COLLATE = utf8_general_ci 
    ROW_FORMAT = Compact;

在上述的建表SQL中,为user_id创建了一个主键索引,然后来查一下当前表的索引信息:

简单的概述一下查询后,每个字段的含义:

  • Table:当前索引属于那张表。
  • Non_unique:目前索引是否属于唯一索引,0代表是的,1代表不是。
  • Key_name:当前索引的名字。
  • Seq_in_index:如果当前是联合索引,目前字段在联合索引中排第几个。
  • Column_name:当前索引是位于哪个字段上建立的。
  • Collation:字段值以什么方式存储在索引中,A表示有序存储,NULL表无序。
  • Cardinality:当前索引的散列程度,也就是索引中存储了多少个不同的值。
  • Sub_part:当前索引使用了字段值的多少个字符建立,NULL表示全部。
  • Packed:表示索引在存储字段值时,以什么方式压缩,NULL表示未压缩,
  • Null:当前作为索引字段的值中,是否存在NULL值,YES表示存在。
  • Index_type:当前索引的结构(BTREE, FULLTEXT, HASH, RTREE)。
  • Comment:创建索引时,是否对索引有备注信息。

这条命令在后续排除问题、性能调优时,会有不小的作用,比如可以通过分析其中的Cardinality字段值,如果该值少于数据的实际行数,那目前索引有可能失效(对于这些后续排查篇和SQL优化篇再聊)。

OK~,到这里了解了一下索引相关的创建、查询命令,接着再看看删除、强制使用命令。

MySQL中并未提供修改索引的命令,也就说当你建错了索引,只能先删再重新建立一次,删除索引的语句如下:

DROP INDEX indexName ON tableName;

当然,当建立了一条索引后,也可以强制性的为SELECT语句指定索引,如下:

SELECT * FROM table_name FORCE INDEX(index_name) WHERE .....;

FORCE INDEX关键字可以为一条查询语句强制指定走哪个索引查询,但要牢记的是:如果当前的查询SQL压根不会走指定的索引字段,哪这种方式是行不通的,这个关键字的用法是:一条查询语句在有多个索引可以检索数据时,显式指定一个索引,减少优化器选择索引的耗时。

但要注意:如果你对于你整个业务系统十分熟悉,那可以这样干。但如果不熟悉的话,还是交给优化器来自行选择,否则会适得其反!

1.3、数据库索引的本质

   前面一直在聊创建、查看、删除、指定等一些索引的基本操作,但索引本质上在数据库中是什么呢?大家都知道,数据库是基于磁盘工作的,所有的数据都会放到磁盘上存储,而索引也是数据的一种,因此与表数据相同,最终创建出的索引也会在磁盘生成本地文件。

   不过索引文件在磁盘中究竟以何种方式存储,这是由索引的数据结构来决定的。同时,由于索引机制最终是由存储引擎实现,因此不同存储引擎下的索引文件,其保存在本地的格式也并不相同。

在这里有一个点需要注意:建立索引的工作在表数据越少时越好,如果你想要给一张百万、千万条数据级别的表新创建一个索引,那创建的耗时也不短,这是为什么呢?

因为刚刚聊过,索引本质上和表是一样的,都是磁盘中的文件,那也就代表着创建一个索引,并不像单纯的给一张表加个约束那么简单,而是会基于原有的表数据,重新在磁盘中创建新的本地索引文件。假设表中有一千万条数据,那创建索引时,就需要将索引字段上的1000W个值全部拷贝到本地索引文件中,同时做好排序并与表数据产生映射关系。

OK~,至此就对MySQL提供的索引机制做了简单回顾,下面再来说说数据库中“多样化”的索引类型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单片机之蓝牙通信

目录 蓝牙介绍 HC05蓝牙模块 HC05参数 HC05引脚 各个引脚功能 HC05模块的作用 工作模式 配置模式 引脚接线 用AT指令进行配置 常用的AT指令 正常模式 测试步骤 烧录的程序 前言: keil文件 蓝牙介绍 蓝牙:Bluetooth,其是低成…

Harmony鸿蒙南向驱动开发-Regulator接口使用

功能简介 Regulator模块用于控制系统中某些设备的电压/电流供应。在嵌入式系统(尤其是手机)中,控制耗电量很重要,直接影响到电池的续航时间。所以,如果系统中某一个模块暂时不需要使用,就可以通过Regulato…

判断系统是debian、centos、Ubuntu的命令

要确认自己的Linux系统是基于Debian的还是其他发行版,你可以使用几种不同的方法。以下是几种常见的方法: cat /etc/os-releaselsb_release -acat /etc/issueunmae -a os-release文件 cat /etc/os-release:这个文件通常包含了关于你的操作系…

【centos】Redis离线安装配置教程

Linux 离线安装Redis配置教程 一、下载二、安装redis三、设置redis开机自启,并且添加到系统服务四、gcc安装 redis官网地址:https://redis.io/ 一、下载 【点击进入下载地址:http://download.redis.io/releases/】选择安装包:re…

【数据结构(五)】栈

❣博主主页: 33的博客❣ ▶️文章专栏分类:数据结构◀️ 🚚我的代码仓库: 33的代码仓库🚚 🫵🫵🫵关注我带你学更多数据结构知识 目录 1.前言2.概念3.栈的使用4.栈的应用场景4.1有效的括号4.2逆波兰表达式4.3栈的压入弹…

直接扩展到无限长,谷歌Infini-Transformer终结上下文长度之争

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 不知 Gemini 1.5 Pro 是否用到了这项技术。 谷歌又放大招了,发布下一代 Transfor…

springboot同时支持jsp+vue页面启动

1、参考文档链接 参考上面文档边百度边改&#xff0c;现在可以了&#xff0c;分享下 2、Java项目目录结构 3、pom.xml内容 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi&quo…

计算机网络 路由器基本配置

一、实验内容 1、按照下表配置好PC机IP地址和路由器端口IP地址 2、配置好路由器特权密文密码“abcd&#xff0b;两位班内序号”和远程登录密码“star” 3、验证测试 a.验证各个接口的IP地址是否正确配置和开启 b.PC1 和 PC2 互ping c.验证PC1通过远程登陆到路由器上&#…

【教学类-52-04】20240412动物数独(4宫格)空1-空15

作品展示 背景需求&#xff1a; 【教学类-52-03】20240412动物数独&#xff08;4宫格&#xff09;难度1-9 打印版-CSDN博客文章浏览阅读603次&#xff0c;点赞20次&#xff0c;收藏8次。【教学类-52-03】20240412动物数独&#xff08;4宫格&#xff09;难度1-9 打印版https://…

MATLAB | 怎样绘制更有立体感的柱状图

之前写了一篇文章说明了MATLAB图例可以自己diy&#xff0c;这次又有了diy的机会&#xff0c;我开发了一个简单的小工具&#xff0c;能够实现绘制伪3d的柱状图&#xff0c;大概效果如下&#xff1a; 使用说明 由于涉及的代码比较接近MATLAB底层的图形对象&#xff0c;有点东西还…

MVCC(解决MySql中的并发事务的隔离性)

MVCC 如何保证事务的隔离性&#xff1f; 1.排他锁&#xff1a;如一个事务获取了一个数据行的排他锁&#xff0c;其他事务就不能再获取改行的其他锁。 2.MVCC&#xff1a;多版本并发控制。 MVCC&#xff1a; 1.隐藏字段 1.DB_TRX_ID&#xff1a;最近修改事务的id。默认值从0开…

4.9总结(Stream流,方法引用概述 || 乘法逆元,组合数)

Stream流 基本概念&#xff1a;以更简便的方式操作集合数据的形式&#xff1b; Steam流的操作步骤&#xff1a; 获取Stream流 中间方法&#xff1a;去重&#xff0c;跳过&#xff0c;获取&#xff0c; 过滤&#xff0c; 合并流&#xff0c;转换类型&#xff1b; 终结方法&…

黑马鸿蒙学习5:渲染foreach

foreach是用来循环渲染界面用的&#xff0c;比如&#xff1a;语法是先定义一个数组&#xff0c;如上图&#xff1a; 其中的keygenerator&#xff0c;其实意思是说&#xff0c;如果要渲染的内容发生了变化&#xff0c;则由于有独特的标识&#xff0c;可以 减少渲染次数。 实例&a…

【linux深入剖析】深入理解基础外设--磁盘以及理解文件系统

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1.磁盘物理结构2.磁盘…

【数据结构】04串

串 1. 定义2. 串的比较3. 串的存储结构4. 具体实现5. 模式匹配5.1 常规思路实现5.2 KMP模式匹配算法5.2.1 next数组计算5.2.1 代码计算next数组5.2.2 KMP算法实现 1. 定义 串(string)是由零个或多个字符组成的有限序列&#xff0c;又叫字符串。 一般记为s a 1 , a 2 , . . . ,…

软件供应链安全:寻找最薄弱的环节

在当今的数字时代&#xff0c;软件占据主导地位&#xff0c;成为全球组织业务和创新的支柱。它是差异化、项目效率、成本降低和竞争力背后的驱动力。软件决定了企业如何运营、管理与客户、员工和合作伙伴的关系&#xff0c;以及充分利用他们的数据。 挑战在于&#xff0c;当今…

【MVCC】深入浅出彻底理解MVCC

MVCC概述 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;即多版本并发控制。主要是为了提高数据库的并发性能而提供的&#xff0c;采用了不加锁的方式处理读-写并发冲突&#xff0c;确保了任何时刻的读操作都是非阻塞的。只需要很小的开销&#xff0c;就可以…

电视盒子哪个好?2024口碑网络电视盒子排行榜

多年来电视盒子始终占据重要地位&#xff0c;功能上并没有受到影响。在这么多品牌中哪些电视盒子的评价是最好的呢&#xff1f;小编根据各大电商平台的用户评价情况整理了口碑最好的网络电视盒子排行榜&#xff0c;跟着小编一起看看市面上的电视盒子哪个好吧。 TOP 1&#xff1…

如何访问远程MySQL数据库?

远程访问MySQL数据库是在不同设备之间实现数据交互的一种方式。通过远程访问&#xff0c;用户可以轻松地操作远程MySQL数据库&#xff0c;从而实现数据的读写、修改和查询等操作。本文将介绍远程访问MySQL数据库的原理和实现方法&#xff0c;以及一种被广泛应用的解决方案【天联…

[入门到放弃]设计模式-笔记

模块化设计 20240448 模块不包含数据&#xff0c;通过实例的指针&#xff0c;实现对实例的操作&#xff1b;唯一包含的数据是用于管理这些模块的侵入式链表模块只负责更具定义的数据结构&#xff0c;执行对应的逻辑&#xff0c;实现不同实例的功能&#xff1b; 参考资料 使用…