⑩② 【MySQL索引】详解MySQL`索引`:结构、分类、性能分析、设计及使用规则。

在这里插入图片描述

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~
个人主页:.29.的博客
学习社区:进去逛一逛~

在这里插入图片描述

MySQL索引

  • ⑩② 【MySQL索引】
    • 1. 索引
    • 2. 索引的结构
      • 🚀B+树索引
      • 🚀Hash索引
      • 🚀思考题
    • 3. 索引的分类
    • 4. 创建、查看、删除索引
    • 5. SQL性能分析
      • 🚀SQL执行频率
      • 🚀慢查询日志
      • 🚀SQL性能分析
        • - profile详情
        • - explain执行计划
    • 6. 索引的使用规则
    • 7. 索引设计原则


⑩② 【MySQL索引】


1. 索引

索引

  • 什么是索引(index) ?
  • 索引(index)是帮助MySQL高效获取数据的数据结构(有序):在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据就是索引。
  • 索引的优缺点?
  • 优势:
    • ⚪提高数据检索效率,降低数据库IO成本;
    • ⚪通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗;
  • 劣势:
    • ⚪索引列需要占用空间,比无索引结构占用的空间更大。
    • ⚪索引虽大大提高了查询效率,但与此同时却降低了更新表的速度,如对表进行INSERT \ UPDATE \ DELETE 时,效率降低。



2. 索引的结构

索引结构

  • MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构。
  • B+Tree索引:最常见的索引类型,大部分引擎都支持B+树索引。
  • Hash索引:底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询。
  • R-tree(空间索引):空间索引是MyISAM引擎的一个特殊索引类型,只要用于地理空间数据类型,较少使用。
  • Full-text(全文索引):是一种通过建立倒排索引,快速匹配文档的方式。类似于ES(Elasticsearch)。
  • 在这里插入图片描述


🚀B+树索引

B+Tree索引

  • 特征:
    • ①每个节点最多可存放4个元素,五个指针
    • 叶子节点形成链表,存储了树的所有元素
    • 指针指向当前元素区间内的元素
  • MySQL索引数据结构对经典的B+Tree进行了优化。在原本B+树的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。
  • 在这里插入图片描述


🚀Hash索引

Hash索引

  • 哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
  • 哈希碰撞问题
  • 如果出现两个或多个键值映射到同一个槽位上,也就是出现hash碰撞时,可以通过链表解决问题。
  • Hash索引特点
    • ① Hash索引只能用于对等比较(=、in),不支持范围查询(between、>、< …)
    • ②无法利用Hash索引完成排序操作
    • ③查询效率高,通常只需要一次检索就可以完成,效率通常要高于B+Tree索引
  • MySQL数据库中,支持hash索引的是Memory引擎,而InnoDB中具有自适应hash功能,hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的。
  • 在这里插入图片描述


🚀思考题

  • 为什么InnoDB存储引擎选择使用B+Tree索引结构?
    • ⚪相对于二叉树,层级更少,搜索效率更高;
    • ⚪对于BTree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,会导致性能下降
    • ⚪相对Hash索引,B+Tree索引支持范围匹配和排序操作;



3. 索引的分类

索引分类

  • ①主键索引 —— PRIMARY

  • ②唯一索引 —— UNIQUE

  • ③常规索引

  • ④全文索引 —— FULLTEXT

  • 在这里插入图片描述

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

    • 聚集索引(Clustered Index):B+Tree叶子节点下挂载这一行的数据
      • ①如果存在主键,主键索引就是聚集索引。
      • ②如果不存在主键,将使用第一个唯一索引**(UNIQUE)作为聚集索引。**
      • ③如果表没有主键,也没有合适的唯一索引InnoDB自动生成一个rowid作为隐藏的聚集索引。
    • 二级索引(Secondary Index):B+Tree叶子节点下挂载这一行的id
    • 在这里插入图片描述



4. 创建、查看、删除索引

索引操作

  • 🚀创建索引

    • -- 使用UNIQUE关键字,创建唯一索引
      -- 使用FULLTEXT关键字,创建全文索引
      -- 不指定上述两者,创建常规索引
      CREATE [UNIQUE | FULLTEXT] INDEX 索引名 ON 表名(字段1,字段2...);
      
  • 🚀查看索引

    • SHOW INDEX FROM 表名;
      
  • 🚀删除索引

    • DROP INDEX 字段名 ON 表名;
      
  • -- 演示:
    
    -- 操作的表tb_user
    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 '系统用户表';
    
    -- 查询索引
    show index from tb_user;
    
    -- 查询所有,竖向显示
    show index from tb_user \G;
    
    -- 1.name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。
    create index idx_user_name on tb_user(name);
    
    -- 2.phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。
    create unique index idx_user_phone on tb_user(phone);
    
    -- 3.为profession、age、status创建联合索引。
    create index idx_user_pro_age_sta on tb_user(profession,age,status);
    
    -- 4.为email建立合适的索引来提升查询效率。
    create index idx_user_email on tb_user(email);
    
    -- 删除索引idx_user_email
    drop index idx_user_email on tb_user;
    



5. SQL性能分析

🚀SQL执行频率

SQL执行频率

  • MySQL客户端连接成功后,通过show [session | global] status命令可以提供服务器状态信息。还可以通过show global status like 'Com_______'命令,查看当前数据库的INSERT \ UPDATE \ DELETE \ SELECT的访问频次。

  • 🚀查看服务器状态信息

    • SHOW [SESSION | GLOBAL] STATUS;
      
  • 🚀查看当前数据库的INSERT \ UPDATE \ DELETE \ SELECT的访问频次

    • -- 模糊匹配中有七个下划线'_'
      SHOW GLOBAL STATUS LIKE 'Com_______';
      


🚀慢查询日志

慢查询日志

  • 慢查询日志记录了所有执行事件超过指定参数long_query_time,单位:秒,默认10秒的所有SQL语句的日志。

  • 🚀MySQL的慢查询日志默认没有开启,需要在MySQL的配置文件/etc/my.cnf中配置相应信息:

    • # /etc/my.cnf文件内:
      #开启MySQL慢查询开关
      slow_query_log=1
      
      #设置慢日志的时间为2秒,SQL语句执行超过2秒,被视为慢查询,记录慢查询日志
      long_query_time=2
      
    • # 修改MySQL配置文件/etc/my.cnf【Linux环境下】
      vi /etc/my.cnf
      
      # 1. 按i键进行编辑
      # 2. 寻找合适位置,输入上文给出的配置信息
      # 3. 按Esc键推出编辑,输入:wq并回车保存退出
      
      # 重启mysql服务器
      systemctl restart mysqld
      
  • 🚀查询慢查询日志是否开启

    • -- OFF代表关闭
      -- ON表示开启
      SHOW VARIABLES LIKE 'slow_query_log';
      
  • 🚀查看慢查询日志内容[Linux环境下]

    • # 慢查询日志保存在:/var/lib/mysql/localhost-slow.log 文件下
      cat /var/lib/mysql/localhost-slow.log
      


🚀SQL性能分析

- profile详情

profile详情

  • show profiles能够在做SQL优化时帮助我们了解时间都耗费在哪里了,通过have_profiling参数,能够看到当前MySQL是否支持查看profile详情。

  • 🚀查看MySQL是否支持查看profile详情

    • select @@have_profiling;
      
  • 🚀开启profiling (默认profiling是关闭的,可使用set语句在session/global级别开启)

    • -- 查看profiling开关是否开启
      select @@profiling;
      
      -- 开启profiling
      set profiling=1;
      
  • 🚀查看每一条SQL耗时基本情况

    • show profiles;
      
  • 🚀查看指定query_id的SQL语句各个阶段的耗时情况

    • show profile for query query_id;
      
  • 🚀查看指定query_id的SQL语句各个阶段耗时以及CPU使用情况

    • show profile cpu for query query_id;
      



- explain执行计划

explain执行计划:

  • EXPLAIN或者DESC命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。

  • 🚀查看SELECT语句执行计划(直接在select语句前加上explain / desc)

    • EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件;
      -- 或
      DESC SELECT 字段列表 FROM 表名 WHERE 条件;
      
  • EXPLAIN执行计划 各个字段含义:

    • id:select查询的序列号,表示查询中执行select子句或者是操作表的顺序(id相同则执行顺序从上到下 、id不同则**值越大越先执行 **)
    • select_type:表示select查询的类型,常见的有:SIMPLE(简单表,不使用表连接或子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(select / where 之后包含了子查询)…
    • type:表示连接类型,性能由好到差的连接类型为:NULL、system、const、eq_ref、ref、range、index、all。
    • possible_key:显示可能引用在这张表上的索引,一个或多个。
    • Key:实际使用的索引,如果为NULL,表示没有使用索引。
    • Key_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。
    • rows:MySQL认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不总是准确的。
    • filtered:表示返回结果的行数占需读取行数的百分比,filtered的值越大越好。
  • 在这里插入图片描述




6. 索引的使用规则

最左前缀法则

如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效)。


范围查询

联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效。


索引列运算

不要再索引列上进行运算操作(max() avg() count()等),否则索引会失效


字符串不加引号

字符串类型字段使用时,若不加引号'',索引失效


模糊查询

如果仅仅是字符串尾部模糊匹配,索引不会失效。如果是字符串头部模糊匹配,索引失效。


使用or来连接条件

用or分割开的条件,如果or前的条件中的列有索引,而or后面的列中没有索引,那么涉及的索引都不会被用到。即or连接的条件都需建立索引才能使得索引生效


数据分布影响

如果MySQL评估使用索引比全表更慢,则不使用索引。


SQL提示

SQL提示,是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化操作的目的。

  • use index():建议查询时使用指定索引

    • SELECT 字段列表 FROM 表名 [USE INDEX(索引名)] WHERE 条件;
      
  • ignore index():建议查询时忽略指定索引

    • SELECT 字段列表 FROM 表名 [IGNORE INDEX(索引名)] WHERE 条件;
      
  • force index():查询时强制使用指定索引

    • SELECT 字段列表 FROM 表名 [FORCE INDEX(索引名)] WHERE 条件;
      

覆盖索引

== 应当尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),从而减少 select * 的使用。 ==

  • explain查看查询计划时,最后一个字段Extra的显示:

    • using index condition:查找使用了索引,但是需要回表查询数据。
    • using where;using index:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据。
  • 思考题:

  • 在这里插入图片描述

  • 答:为id、password字段创建联合索引,这样就实现了覆盖索引,且不需要回表查询,效率高。


前缀索引

当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率

  • 🚀选取部分前缀建立索引

    • CREATE INDEX 索引名 ON 表名(column(前缀长度));
      
    • 前缀长度:

      • 可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。

      • -- 计算tb_user表 字段email 的选择性
        select count(distinct email) / count(*) from tb_user;
        
        -- 原本基础上,设置前缀长度为5,计算选择性
        select count(distinct substring(email,1,5)) / count(*) from tb_user;
        

单列索引 和 联合索引

  • 单列索引:一个索引只包含单个列
  • 联合索引:一个索引包含了多个列
  • 在业务场景中,如果存在多个查询条件,考虑针对查询字段检索引时,建议建立联合索引,而非单列索引。



7. 索引设计原则

  • 1.针对于数据量较大,且查询比较频繁的表建立索引。

  • 2.针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。

  • 3.尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。

  • 4.如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引

  • 5.尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。

  • 6.要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。

  • 7.如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。




在这里插入图片描述

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

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

相关文章

Wordpress多语言插件:WPML插件使用教程,最佳的多语言建站方案

今天小编讲的是另外一款多语言插件WPML。相比Gtranslate采用的是机器翻译,难免存在翻译不准确,词不达意的情况,WPML可以支持人工翻译内容添加。 事先说明一点:用插件实现多语言较为方便,但此方法做出的多语言网站SEO性能一般,只建议展示站使用,如果想要SEO营销型多语言网…

猫罐头哪个牌子好?盘点十大猫罐头品牌排行榜!

作为一个多猫家庭的铲屎官&#xff0c;我之前一直购买性价比较高的德国进口猫罐头。然而&#xff0c;近来进口主食罐的频繁涨价让我不得不开始关注国产主食罐。在这篇文章中&#xff0c;我想与大家分享一些口碑较好的国产猫罐头品牌&#xff0c;希望能对你的选购决策提供一些参…

image is being used by stopped container 7d2ff8620f3b 删除镜像失败怎么办

这个错误信息表明&#xff0c;镜像 55860ee0cd73 正被一个已停止的容器 7d2ff8620f3b 使用&#xff0c;因此无法正常删除。要解决这个问题&#xff0c;你有两个选择&#xff1a; 删除使用该镜像的容器&#xff1a;首先删除引用该镜像的容器&#xff0c;然后再删除镜像。这可以通…

素质教育正式提出30周年 提高实际应用能力成为教育新选择

至2023年“素质教育”已正式提出30周年。在实施期间,素质教育取得了显著成就:不仅提高了学生的综合素质和竞争力,培养了学生的创新能力、实践能力等,同时也改变了应试导向和知识灌输的教育模式,建立了以人为本、以学为主的教育理念。 教育观念发生扭转,教育目标也随之改变。学…

猫罐头哪个牌子好?分享十款猫罐头品牌排行榜!

选择适合的猫罐头非常重要&#xff0c;好的猫罐头应该提供丰富的营养、适量的水分、口感良好&#xff0c;并且易于消化吸收。然而&#xff0c;如果选择不当&#xff0c;可能无法达到期望的效果&#xff0c;甚至可能对猫咪产生负面影响。 作为一位经营猫咖5年的老板&#xff0c;…

非 dict 字典类型的处理

在Python的requests库中&#xff0c;使用data参数发送POST请求时&#xff0c;如果传入的数据对象不是直接继承自dict的字典类型&#xff0c;就会抛出TypeError异常。 Python的requests库是一个广泛用于HTTP请求的库&#xff0c;它提供了丰富的功能来发送和处理HTTP请求。其中&…

原论文一比一复现 | 更换 RT-DETR 主干网络为 【VGG13】【VGG16】【VGG19】| 对比实验必备

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 论文地址:https://arxiv.o…

BUG 随想录 - Java: 程序包 com.example.xxx 不存在

目录 一、BUG 复现 二、解决问题 一、BUG 复现 背景&#xff1a;通过 feign 的最佳实践&#xff0c;将 feign 单独提取成一个微服务&#xff0c;接着在需要远程调用的微服务中引入 feign 模块&#xff0c;并在启动类通过 EnableFeignClients 声明指定的 Feign 客户端. 出现问题…

搭建帮助中心系统!客户服务一站式解决方案

随着企业规模的扩大和客户需求的增加&#xff0c;提供高效、便捷的客户服务变得越来越重要。为了满足客户的需求&#xff0c;许多企业开始搭建帮助中心系统&#xff0c;为客户提供一站式的问题解决方案。接下来就跟大家介绍一下帮助中心系统&#xff0c;以及如何实现一流的客户…

图解分布式事务实现原理(三)

参考 本文参考https://zhuanlan.zhihu.com/p/650791238从零到一搭建 TCC 分布式事务框架&#xff0c;并在小徐的基础上增加个人见解笔记。 项目地址&#xff1a;https://github.com/xiaoxuxiansheng/gotcc 图解分布式事务实现原理&#xff08;一&#xff09;&#xff1a;https…

云骑士数据恢复软件会对硬盘造成伤害吗?

当今时代&#xff0c;数据已经成为我们生活的重要组成部分&#xff0c;而硬盘又是存储数据的主要设备之一。然而&#xff0c;由于各种原因&#xff0c;我们的数据很容易丢失。是的&#xff0c;我们可以通过数据恢复软件来找回丢失的数据&#xff0c;但是这个过程是否会对硬盘造…

系列五、GC垃圾回收【四大垃圾算法-复制算法】

一、堆的内存组成 二、复制算法 2.1、发生位置 复制算法主要发生在新生代&#xff0c;发生在新生代的垃圾回收也被叫做Minor GC。 2.2、 Minor GC的过程 复制>清空》交换 1、eden、from区中的对象复制到to区&#xff0c;年龄1 首先&#xff0c;当eden区满的时候会触发第一…

微软Ignite 2023大盘点:GPT-4 Turbo、DALL-E 3等

11月16日&#xff0c;微软在美国西雅图举办“Microsoft Ignite 2023”全球开发者大会。ChatGPT等生成式AI成为了本次大会的重要主题。 下面「AIGC开放社区」将根据大会发布的内容&#xff0c;盘点重要内容。 GPT-4 Turbo、 DALL E 3等全新模型 16K上下文的新GPT-3.5 Turbo模…

五分钟,Docker安装kafka 3.5,kafka-map图形化管理工具

首先确保已经安装docker&#xff0c;如果是windows安装docker&#xff0c;可参考 wsl2安装docker 1、安装zk docker run -d --restartalways -e ALLOW_ANONYMOUS_LOGINyes --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name zookeeper -p 2181:218…

操作指南|JumpServer堡垒机支持通过Passkey进行登录认证

伴随着互联网应用的深度普及&#xff0c;用户账户安全的重要性不言而喻。密码是目前互联网用户保护在线账户安全和隐私的主要手段。然而&#xff0c;传统密码技术本身也存在着一些缺陷。 首先&#xff0c;密码是由用户创建的&#xff0c;用户通常会出于易用性而非实际的安全性…

解决 uniapp 开发微信小程序 不能使用本地图片作为背景图 问题

参考博文&#xff1a;uniapp微信小程序无法使用本地静态资源图片(背景图在真机不显示)的解决方法_javascript技巧_脚本之家 问题&#xff1a;uniapp 开发微信小程序&#xff0c;当使用本地图片作为 background-image 时&#xff0c;真机无法显示 解决&#xff1a; 方法一&am…

Java智慧工地SaaS管理平台源码:AI/云计算/物联网

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…

招聘全球视野:跨境电商的人才策略

在数字时代&#xff0c;跨境电商已经成为全球商业领域的引擎之一。由于全球市场的巨大潜力&#xff0c;跨境电商企业需要确保其人才团队具备全球视野和战略洞察力&#xff0c;以在竞争激烈的环境中脱颖而出。本文将深入探讨招聘全球视野的重要性&#xff0c;并提供一些战略性的…

【开源】基于JAVA的高校宿舍调配管理系统

项目编号&#xff1a; S 051 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S051&#xff0c;文末获取源码。} 项目编号&#xff1a;S051&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统…

SQLMAP --TAMPER的编写

跟着师傅的文章进行学习 sqlmap之tamper脚本编写_sqlmap tamper编写-CSDN博客 这里学习一下tamper的编写 这里的tamper 其实就是多个绕过waf的插件 通过编写tamper 我们可以学会 在不同过滤下 执行sql注入 我们首先了解一下 tamper的结构 这里我们首先看一个最简单的例子…