MySQL 中的索引

MySQL 中的索引

  • 一、索引的创建和删除
    • 1.主键会自动添加索引
    • 2.unique 约束的字段自动添加索引
    • 3.给指定的字段添加索引
    • 4.删除指定索引
    • 5.查询表上的索引
  • 二、索引的分类
  • 三、MySQL索引采用了B+树数据结构
    • 1.B+树的经典面试题
  • 四、其他索引及相关调优
    • 1.Hash索引
    • 2.聚集索引和非聚集索引
    • 3.二级索引
    • 4.覆盖索引
    • 5.索引下推
    • 6.单列索引(单一索引)
    • 7.复合索引(组合索引)
  • 五、索引的优缺点
  • 六、何时使用索引


  • 索引(index)是一种能够提高检索(查询)效率的提前排好序的数据结构。例如:书的目录就是一种索引机制。索引是解决 SQL 慢查询的一种方式。

一、索引的创建和删除

1.主键会自动添加索引

  • 主键字段会自动添加索引,不需要程序员干涉,主键字段上的索引被称为主索引

2.unique 约束的字段自动添加索引

  • unique约束的字段也会自动添加索引,不需要程序员干涉,这种字段上添加的索引称为唯一索引

3.给指定的字段添加索引

  • 建表时添加索引:

    drop table if exists test;
    create table test (id int primary key auto_increment,name varchar(255),index index_name(name)
    );
    
  • 如果表已经建好了,后期给字段添加索引:

    alter table test add index index_age (age);
    
  • 直接创建索引:

    create index index_age on test(age);
    

4.删除指定索引

  • 删除索引:

    alter table test drop index index_name;
    

5.查询表上的索引

  • 查询指定表上的所有索引:
    show index from test;
    
    在这里插入图片描述

二、索引的分类

  • 不同的存储引擎有不同的索引类型和实现:
    • 按照数据结构分类:
      • B+树 索引:(MySQL 的 InnoDB 存储引擎采用的就是这种索引) 采用 B+树 的数据结构。
      • Hash 索引:(仅 memory 存储引擎支持)采用 哈希表 的数据结构。
    • 按照物理存储分类:
      • 聚集索引(聚簇索引):索引和表中的数据放在一起,数据存储的时候就是按照索引顺序存储的。一张表只能有一个聚集索引。
      • 非聚集索引(非聚簇索引):索引和表中数据是分开的,索引是独立于表空间的,一张表可以有多个非聚集索引。
    • 按照字段特性分类:
      • 主键索引(primary key)
      • 唯一索引(unique)
      • 普通索引(index)
      • 全文索引(fulltext:仅 InnoDBMyISAM 存储引擎):要求字段的类型都是文本内容才可以使用全文索引。
    • 按照字段个数分类:
      • 单列索引(单一索引)、联合索引(复合索引、组合索引)

三、MySQL索引采用了B+树数据结构

  • 关于这部分知识可以参考我博客===>查找中常见的树数据结构

1.B+树的经典面试题

  • 经典面试题: MySQL为什么选择B+树作为索引的数据结构,而不是B树?
    1. 非叶子节点上可以存储更多的键值,阶数可以更大,更矮胖,磁盘IO次数少,数据查询效率高。
    2. 所有数据都是有序存储在叶子节点上的,让范围查找,分组查找效率更高。
    3. 数据页之间、数据记录之间采用指针链接,让升序降序更加方便操作。
  • 经典面试题: 如果一张表没有主键索引,那还会创建B+树吗?
    • 当一张表没有主键索引时,默认会使用一个隐藏的内置的聚集索引(clustered index)。这个聚集索引是基于表的物理存储顺序构建的,通常是使用B+树实现的。

四、其他索引及相关调优

1.Hash索引

  • 支持Hash索引的存储器引擎有:
    • InnoDB(不支持手动创建Hash索引,系统会自动维护一个自适应的Hash索引
      • 对于 InnoDB 来说,即使手动指定了某字段采用Hash索引,最终show index from 表明的时候,还是BTREE
    • Memory(支持Hash索引)。
  • Hash索引底层的数据结构就是哈希表。一个数组,数组中每个元素是链表。和Java中的HashMap一样。哈希表中每个元素都是key value结构。key存储索引值value存储行指针
    在这里插入图片描述
  • 注意:不同的字符串,经过哈希算法得到的数组下标可能相同,这种叫做哈希碰撞/哈希冲突。【不过,好的哈希算法应该具有很低的碰撞概率。常用的哈希算法如 MD5、SHA-1、SHA-256 等都被设计为尽可能减少碰撞的发生。】
  • Hash索引的优缺点:
    • 优点:只能用在点查询中效率很高。例如:age=10。
    • 缺点:不支持排序,不支持范围查找。

2.聚集索引和非聚集索引

  • 按照数据的物理存储方式不同,可以将索引分为聚集索引(聚簇索引)非聚集索引(非聚簇索引)
    • 存储引擎是InnoDB的,主键上的索引属于聚集索引
      • InnoDB的物理存储方式:当创建一张表user,并使用InnoDB存储引擎,会在硬盘上生成这样的文件:
        • user.ibl(InnoDB data表索引+数据)
        • user.frm(存储表结构信息)
    • 存储引擎是MyISAM的,任意字段上的索引都是非聚集索引
      • MyISMA的物理存储方式:当创建一张表user,并使用MyISAM存储引擎,会在硬盘上生成这样的文件:
        • user.MYD(表数据)
        • user.MYI(表索引)
        • user.frm(表结构)
    • 注意:从 MySQL8.0开始,不再生成frm文件了,引入了数据字典,用数据字典来统一存储表结构信息,例如:
      • information_schema.TABLES(表包含了数据库中所有表的信息,例如表名、数据库名、存储引擎类型等。)
      • information_schema.COLUMNS(表包含了数据库中所有表的列信息,例如列名、数据类型、默认值等。)
        在这里插入图片描述
        在这里插入图片描述
  • 聚集索引的优点和缺点:
    • 优点:聚集索引将数据存储到索引树的叶子节点上。可以减少一次查询,因为查询索引树的同时可以获取数据。
    • 缺点:对数据进行修改或删除时需要更新索引树,会增加系统的开销。

3.二级索引

  • 二级索引也属于非聚集索引。也有人把二级索引称为辅助索引。
    在这里插入图片描述
    在这里插入图片描述

4.覆盖索引

  • 覆盖索引(Covering Index),顾名思义,是指某个查询语句可以通过索引的覆盖来完成,而不需要回表查询真实数据。其中的覆盖指的是在执行查询语句时,查询需要的所有列都可以从索引中提取到,而不需要再去查询实际数据行获取查询所需数据。

  • 假设有一个用户表(user)包含以下列:id,username,email,age。

  • 常见的查询是根据用户名查询用户的邮箱。如果为了提高这个查询的性能,可以创建一个覆盖索引,包含(username,email)这两列。

  • 创建覆盖索引:

    create index index_uername_email on user(username, email);
    
  • 当执行以下查询时:

    select email from user where username='jack';
    
  • MySQL可以直接使用覆盖索引(index_username_email)来获取查询结果,而不必再去查找用户表中的数据。这样可以减少磁盘IO并提高查询效率。而如果没有覆盖索引,MySQL会先使用索引(username)来匹配行,然后再回到表查询获取email,这个过程会增加更多的磁盘IO和查询时间。

  • 值得注意的是:覆盖索引的创建需要考虑查询的字段选择。如果查询需要的字段较多,可能需要创建包含更多列的覆盖索引,以满足完全覆盖查询的需要。

5.索引下推

  • 索引下推(Index Condition Pushdown)是一种MySQL中的优化方法,它可以将查询中的过滤条件下推到索引层级中处理,从而减少回表次数,优化查询性能。
  • 具体来说,在使用索引下推时,MySQL
    在这里插入图片描述
    在这里插入图片描述

6.单列索引(单一索引)

  • 单一索引是指对数据库表中的某一列或属性进行索引创建,对该列进行快速查找和排序操作。单一索引可以加快查询速度,提高数据库的性能。

  • 例如:假设我们有一个学生表(student),其中有以下几个列:学生编号(stu_id)、姓名(name)、年龄(age)和性别(sex)。

  • 如果我们针对学生表的信息编号(stu_id)列创建单列索引,那么可以快速地根据学生编号进行查询或者排序操作。例如,我们可以使用下面的SQL语句查询学生编号为123456的学生信息:

    select * from student where stu_id='123456';
    
  • 由于我们对学生编号建立了单一索引,所以数据库可以直接通过索引快速定位到具有学生123456的那一行记录,从而加快查询速度。

7.复合索引(组合索引)

在这里插入图片描述


五、索引的优缺点

  • 索引是数据库中一种重要的数据结构,用于加速数据的检索和查询操作。它的优点和缺点如下:
  • 优点:
    1. 提高查询性能:通过创建索引,可以大大减少数据库查询的数据量,从而提高查询的速度。
    2. 加速排序:当查询需要按照某个字段进行排序时,索引可以加速排序的过程,提高排序的效率。
    3. 减少磁盘IO:索引可以减少磁盘IO的次数,这对于磁盘读写速度较低的场景,尤其重要。
  • 缺点:
    1. 占据额外的存储空间:索引需要占据额外的存储空间,特别是在大型数据库系统中,索引可能占据较大的空间。
    2. 增删改操作的性能损耗:每次对数据表进行插入、更新、删除等操作时,需要更新索引,会导致操作的性能降低。
    3. 资源消耗较大:索引需要占用内存和CPU资源,特别是在大规模并发访问的情况下,可能对系统的性能产生影响。

六、何时使用索引

  • 在以下情况下建议使用索引:
    1. 在需要经常搜索的列上创建索引。
    2. 主键上创建索引(MySQL中主键自动创建索引)。
    3. 经常用于连接的列上创建索引。
    4. 经常需要根据范围查询进行搜索的列上创建索引。
    5. 在 Where 查询子句中引用效率高的列上创建索引。
    6. 在 Order by 和 Group by 子句中出现的列上创建索引。
    7. 大表:当表的数据量较大时,使用索引可以快速定位到所需的数据,提高查询效率。
    • 注意:在某一范围内频繁搜索的属性,只有在当使用索引的查询结果不超过总记录的20%时才有明显效果
  • 在以下情况下不建议使用索引:】
    1. 频繁执行更新操作的表:如果表经常被更新数据,使用索引可能会降低更新操作的性能,因为每次更新都需要维护索引。
    2. 小表:对于数据量小的表,使用索引可能并不会带来明显的性能提升,反而会占用额外的存储空间。
    3. 对于唯一性很差的字段,一般不建议添加索引。当一个字段的唯一性很差时,查询操作基本上需要扫描表的大部分数据。如果为这样的字段创建索引,索引的大小可能会比数据本身还大,导致索引的存储空间占用过高,同时也会导致查询操作的性能下降。
  • 总之,索引需要根据具体情况进行使用和权衡,需要考虑到表的大小、查询频率、更新频率以及业务需求等多方面的因素。

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

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

相关文章

【linux线程(四)】初识线程池手撕线程池

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:Linux从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学更多操作系统知识   🔝🔝 Linux线程池 1. 前言2. 什么是…

Python 从0开始 一步步基于Django创建项目(3)使用Admin site管理数据模型

本文内容建立在《Python 从0开始 一步步基于Django创建项目(2)创建应用程序&数据模型》的基础上。 Django提供的admin site,使得网站管理员,能够轻松管理网站的数据模型。 本文首先创建‘管理员账户’,即超级用户…

华为OD机22道试题

华为OD机试题 2.查找小朋友的好朋友位置 在学校中,N 个小朋友站成一队,第 i 个小朋友的身高为 height[i],第 i 个小朋友可以看到第一个比自己身高更高的小朋友j,那么 j 是 i 的好朋友 (要求:j>i) 。 请重新生成一个…

202305 CSP认证

202305-1 重复局面 第一题直接干 #include<bits/stdc.h> using namespace std; unordered_map<string, int> chess; int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);string line, str ""; int n;cin >> n;while(n --){str …

数据结构:链式队列

1.设计思想&#xff1a; 我们可以设计出以上五种队列&#xff0c;但是基于时间复杂度&#xff0c;和空间复杂度的最优解&#xff0c;我们选择入队和出队均为O(1)的&#xff0c;也就是第五种 2.结构设计 typedef struct LPNode//数据节点 {int data;//数据struct LPNode* next…

Redis消息队列与thinkphp/queue操作

业务场景 场景一 用户完成注册后需要发送欢迎注册的问候邮件、同时后台要发送实时消息给用户对应的业务员有新的客户注册、最后将用户的注册数据通过接口推送到一个营销用的第三方平台。 遇到两个问题&#xff1a; 由于代码是串行方式&#xff0c;流程大致为&#xff1a;开…

基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的捕获模式(外部中断)应用

基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的捕获模式(外部中断)应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC12C5A60S2系列1T 805…

【Langchain-Chatchat】部署ChatGLM3-6B-32K教程

介绍 Langchain-Chatchat这个框架可以帮助我们更容易的部署大语言模型&#xff0c;之前也写过ChatGLM传统的部署教程&#xff0c;有兴趣的可以参考 【ChatGLM3】第三代大语言模型多GPU部署指南【ChatGLM2-6B】从0到1部署GPU版本 借助Langchain-Chatchat框架&#xff0c;可以…

32串口学习

基于之前的GPIO等工程&#xff0c;后面的上手难度就简单多了&#xff0c;主要是相关寄存器的设置。 void USART1_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART1 clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph…

计算机网络:信道复用技术概念解析

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

数据结构从入门到精通——希尔排序

希尔排序 前言一、希尔排序( 缩小增量排序 )二、希尔排序的特性总结三、希尔排序动画演示四、希尔排序具体代码实现test.c 前言 希尔排序是一种基于插入排序的算法&#xff0c;通过比较相距一定间隔的元素来工作&#xff0c;各趟比较所用的距离随着算法的进行而减小&#xff0…

【前端】Web API

1.Web API 简介 JS分为三大部分&#xff1a; ESCMScript&#xff1a;基础语法部分DOM API&#xff1a;操作页面结构BOM API&#xff1a;操作浏览器 Web API包含 DOM BOM 2.DOM基本概念 DOM全称 Document Object Mod…

最短路算法

数据结构、算法总述&#xff1a;数据结构/算法 C/C-CSDN博客 目录 朴素dijkstra算法 堆优化版dijkstra算法 Bellman-Ford算法 spfa 算法&#xff08;队列优化的Bellman-Ford算法&#xff09; spfa判断图中是否存在负环 floyd算法 朴素dijkstra算法 思路&#xff1a; 集合…

Linux相关命令(2)

1、W &#xff1a;主要是查看当前登录的用户 在上面这个截图里面呢&#xff0c; 第一列 user &#xff0c;代表登录的用户&#xff0c; 第二列&#xff0c; tty 代表用户登录的终端号&#xff0c;因为在 linux 中并不是只有一个终端的&#xff0c; pts/2 代表是图形界面的第…

长三角科技盛会“2024南京国际人工智能,机器人,自动驾驶展览会”

2024南京国际人工智能,机器人,自动驾驶展览会 2024 Nanjing International Ai, Robotics, Autonomous Driving Expo 时间:2024年11月22-24日 地点:南京国际博览中心 南京&#xff0c;这座历史悠久的文化名城&#xff0c;如今正站在新一轮科技产业变革的前沿&#xff0c;以人工…

院子摄像头的监控

院子摄像头的监控和禁止区域入侵检测相比&#xff0c;多了2个功能&#xff1a;1&#xff09;如果检测到有人入侵&#xff0c;则把截图保存起来&#xff0c;2&#xff09;如果检测到有人入侵&#xff0c;则向数据库插入一条事件数据。 打开checkingfence.py&#xff0c;添加如下…

Springboot笔记-03

1.properties配置文件 #配制oerson的值 person.lastname张三 person.age12 person.birth2017/12/12 person.bossfalse person.dog.namedag person.dog.age15 person.maps.k1v1 person.maps.k212 person.listsa,b,c运行结果乱码 因为idea默认是utf-8编码而properties是ascall编…

Bytebase 2.14.1 - 分支 (Branching) 功能支持 Oracle

&#x1f680; 新功能 分支 (Branching) 功能支持 Oracle。为 SQL 编辑器添加了项目选择器。 新增 SQL 审核规范&#xff1a; 禁止混合 DDL、DML 语句。禁止对同一张表进行不同类型的 DML 变更 (UPDATE,INSERT,DELETE)。 &#x1f514; 重大变更 工作空间设置中的「数据访问…

大屏可视化综合展示解决方案

1.系统概述 1.1.需求分析 1.2.重难点分析 1.3.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 2.3.接口及要求 3.系统功能设计 3.1.功能清单列表 3.2.数据源管理 3.3.数据集管理 3.4.视图管理 3.5.仪表盘管理 3.6.移动端设计 3.1.系统权限设计 3.…

利用Scala与Apache HttpClient实现网络音频流的抓取

概述 在当今数字化时代&#xff0c;网络数据的抓取和处理已成为许多应用程序和服务的重要组成部分。本文将介绍如何利用Scala编程语言结合Apache HttpClient工具库实现网络音频流的抓取。通过本文&#xff0c;读者将学习如何利用强大的Scala语言和Apache HttpClient库来抓取网…