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. 对于唯一性很差的字段,一般不建议添加索引。当一个字段的唯一性很差时,查询操作基本上需要扫描表的大部分数据。如果为这样的字段创建索引,索引的大小可能会比数据本身还大,导致索引的存储空间占用过高,同时也会导致查询操作的性能下降。
  • 总之,索引需要根据具体情况进行使用和权衡,需要考虑到表的大小、查询频率、更新频率以及业务需求等多方面的因素。

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

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

相关文章

专业130+总分410+西南交通大学924信号与系统考研经验西南交大电子信息通信工程,真题,大纲,参考书。

初试分数出来,专业课924信号与系统130,总分410,整体上发挥正常,但是还有遗憾,其实自己可以做的更好,总结一下经验,希望对大家有所帮助。专业课:(130) 西南交…

机器学习——决策树特征选择准则

机器学习——决策树特征选择准则 决策树是一种强大的机器学习模型,它可以用于分类和回归任务。决策树通过树状结构对数据进行分类,每个内部节点表示一个特征,每个叶节点表示一个类别或一个数值。在决策树构建的过程中,特征的选择…

JSqlParser的使用

简介 JSqlParse是一款很精简的sql解析工具,它可以将常用的sql文本解析成具有层级结构的语法树,我们可以针对解析后的节点进行处理(增加、移除、修改等操作),从而生成符合我们业务要求的sql,比如添加过滤条件等等 JSqlParse采用访问者模式 项…

随笔】Git -- 基本概念和使用方式(五)

💌 所属专栏:【Git】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大…

鸿蒙Harmony应用开发—ArkTS(stateStyles:多态样式)

Styles和Extend仅仅应用于静态页面的样式复用,stateStyles可以依据组件的内部状态的不同,快速设置不同样式。这就是我们本章要介绍的内容stateStyles(又称为:多态样式)。 概述 stateStyles是属性方法,可以…

【工具使用】VScode如何设置中文环境

操作步骤 1.1 安装中文插件 1.2 设置为中文,然后重启 按照插件的使用方法介绍设置中文: 按下“CtrlShiftP”组合键以显示“命令面板”: 输入“dispaly”,选择“Configure Display Language”: 选择“中文简体” …

Python Flask 表单的使用

新建templ;ates/index.html 内容如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <form action"">账号&#xff1a;<input …

能耗采集与分析 用能计费与收费【产业园区综合计费——安科瑞解决方案】

背景 2022年《非电网直接供电电费收取公示暂行办法》的通知要求由商业综合体、产业园区、物业、写字楼等供电主体体应按照终端用户用电电压等级对应的目录电价收取电费&#xff0c;不得在电费中加收其他费用。&#xff0c;按照“终端用户用电电压等级目录平段电价上浮幅度”确…

Docker构建多平台(x86,arm64)构架镜像

这里写自定义目录标题 背景配置buildx开启experimental重启检查 打包 背景 docker镜像需要支持不同平台架构 配置buildx 开启experimental vi /etc/docker/daemon.json {"experimental": true }或者 重启检查 # 验证buildx版本 docker buildx version# 重启do…

MNN 执行推理(九)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session 之维度计算&#xff08;五…

基于python+vue的O2O生鲜食品订购flask-django-nodejs-php

近年来互联网络的迅猛发展和电子终端设备的普及&#xff0c;赋予了各行业充足的发展空间。微信小程序的O2O生鲜食品订购相比于传统信息技术&#xff0c;时效性是它最大的特色&#xff0c;已经在电子娱乐、经济等中发挥着举足轻重的作用。短时间内迅速扩大了线上管理系统的规模。…

【QT入门】 Qt自定义信号后跨线程发送信号

往期回顾&#xff1a; 【QT入门】 lambda表达式(函数)详解-CSDN博客 【QT入门】 Qt槽函数五种常用写法介绍-CSDN博客 【QT入门】 Qt实现自定义信号-CSDN博客 【QT入门】 Qt自定义信号后跨线程发送信号 由于Qt的子线程是无法直接修改ui&#xff0c;需要发送信号到ui线程进行修改…

Linux centos 安装PHP8.2或其他版本等 仍显示5.4或者其他版本---需要修改环境变量

查询php文件 find / -name php 在不同的文件夹下查看php版本&#xff08;php安装路径每个人不一样&#xff0c;根据自己查到的php冷路径去执行&#xff09; 解决方法&#xff1a;环境变量中加上正确PHP版本的路径 编辑环境变量文件 vim /etc/profile 在文件里增加如何代码…

如何使用Excel创建一个行政考勤表

在企业和机构中&#xff0c;行政考勤管理是一项重要的日常工作&#xff0c;它涉及到员工的出勤情况、请假记录、加班情况等。使用Excel创建一个行政考勤表可以帮助管理者有效地记录和跟踪员工的考勤情况&#xff0c;下面将详细介绍如何使用Excel创建一个行政考勤表。 第一部分&…

重新配置node.js,npm,环境变量

起因是检查最近收到的一些朋友分享给我的各种资料&#xff0c;什么前端&#xff0c;后端&#xff0c;java,go,python等语言&#xff0c;想着将一个模拟QQ音乐的一个源代码进行跑通&#xff0c;看看有什么特别之处。如下图 出现了node环境路径问题&#xff0c;参考链接 https:/…

小孔平板应力集中问题matlab有限元编程【源码+PPT讲义】|三节点三角形单元|平面单元|稀疏矩阵 |Comsol网格

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

Domino中启用IPv6支持

大家好&#xff0c;才是真的好。 虽然这周末的新闻很多&#xff0c;例如HCL又发布了Nomad Web 1.0.11,还有Verse 3.2.1等更新。 但是但是&#xff0c;每周五的新闻大家看得很少&#xff0c;所以我们……留到下周五再讲述产品更新的新闻和信息吧。 今天讲的是Domino中如何启用…

【图解物联网】第6章 物联网与数据分析

6.1 传感器数据与分析 从前几章中我们已经了解到&#xff0c;只要把配备传感器的设备连接到网络&#xff0c;就能把所有的信息采集到物联网服务之中&#xff08;图6.1&#xff09;。 从工业角度而言&#xff0c;给工厂中的生产流水线和流通的产品打上电子标签&#x…

每日五道java面试题之springboot篇(二)

目录&#xff1a; 第一题. 你如何理解 Spring Boot 配置加载顺序&#xff1f;第二题. Spring Boot 中如何解决跨域问题 ?第三题. 什么是 CSRF 攻击&#xff1f;第四题. 比较一下 Spring Security 和 Shiro 各自的优缺点 ?第五题. bootstrap.properties 和 application.proper…

hcia datacom课程学习(3):http与https、FTP

1.超文本传输协议&#xff1a;http与https &#xff08;1&#xff09;用来访问www万维网。 wwwhttp&#xff0b;html&#xff0b;URLweb &#xff08;2&#xff09;它们提供了一种发布和接受html界面的方法&#xff1a;当在网页输入URL后&#xff0c;从服务器获取html文件来…