Mysql进阶(三)之索引篇

文章目录

  • 前言
  • 索引介绍
    • 1.什么是索引?
    • 2.优缺点
    • 3.什么时候需要 / 不需要索引?
    • 4.语法
  • 索引底层结构
    • 1.Hash表
    • 2.B+Tree
  • 索引分类
    • 1.按字段特性
    • 2.按物理存储
    • 3.按字段个数
  • 索引优化
    • 1.SQL性能分析
    • 2.索引失效
    • 3.常见索引优化方法

前言

以面试题驱动索引的学习:
1.索引底层使用了什么数据结构和算法?
2.为什么 MySQL InnoDB 选择 B+tree 作为索引的数据结构?
3.什么时候适用索引?
4.什么时候不需要创建索引?
5.什么情况下索引会失效?
6.有什么优化索引的方法?

索引介绍

1.什么是索引?

索引是一种用于快速查询和检索数据的数据结构, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

2.优缺点

  • 优点:使用索引可以大大加快 数据的检索速度(大大减少检索的数据量)。通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

  • 缺点:创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。索引需要使用物理文件存储,也会耗费一定空间

3.什么时候需要 / 不需要索引?

正如上面讲的索引的优缺点,可以看出,索引并不是万能的,也有自己的适用范围。所以再详细说一下索引的使用场景。

什么时候适用索引?
(1)一般来说,如果一个字段具有唯一性约束(主键),那么索引会有很大好处。
(2)如果要用where对某些字段进行条件查询,那么为这个字段创建索引后会增加查询效率
(3)经常用于 GROUP BY 和 ORDER BY 的字段(B+Tree是排好序的)

什么时候不需要创建索引?
(1)数据量比较少,可以不创建索引
(2)where,group by 等查询条件用不到的字段
(3)字段中存在大量重复数据,不需要创建索引,比如性别字段,只有男女
(4)经常更新的字段不用创建索引,因为索引字段频繁修改,就需要频繁的重建索引

4.语法

(1)创建索引:

CREATE  [ UNIQUE | FULLTEXT ]  INDEX  index_name  ON  table_name  ( index_col_name,... ) ;

在这里插入图片描述

(2)查看索引

SHOW  INDEX  FROM  table_name ;

在这里插入图片描述

(3)删除索引

DROP  INDEX  index_name  ON  table_name ;

索引底层结构

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,常用的有以下几种:
B+Tree 索引、HASH 索引、Full-Text 索引。

在这里插入图片描述

InnoDB 是在 MySQL 5.5 之后成为默认的 MySQL 存储引擎B+Tree 索引类型也是 MySQL 存储引擎采用最多的索引类型。

1.Hash表

哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中
缺点:只能等值查询(很快),不能范围查询

2.B+Tree

说到为什么要用B+Tree作为索引结构,那演变顺序(选择顺序)应该是:二叉树——二叉搜索树——平衡二叉树——红黑树——B-Tree——B+Tree,详见这篇文章

简单说一下前面几个的缺点:
二叉树:插入没有顺序,查找起来性能肯定很差
二叉搜索树:虽然插入有顺序了,但如果是顺序插入,会形成一个链表,查询性能降低
平衡二叉树&红黑树:都可以自平衡,但是当节点增多时,树的深度会变大

总结一下:其实上面几种都没能解决随着节点增多树的高度变高(导致IO查询次数增多),所以直接想到多叉树——B-Tree & B+Tree,即多路平衡二叉树

B-Tree
在这里插入图片描述

B+Tree
在这里插入图片描述

可以看出B-Tree和B+Tree的区别:

  • B 树的所有节点既存放键(key) 也存放 数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。
  • B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。

Mysql对B+Tree做了一点改进,,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能,利于排序。
在这里插入图片描述

索引分类

在创建表时,InnoDB 存储引擎会根据不同的场景选择不同的列作为索引:

1.按字段特性

主要分为:主键索引、唯一索引、常规索引、全文索引
在这里插入图片描述

2.按物理存储

分为聚簇索引(主键索引)、二级索引(辅助索引)
在这里插入图片描述
聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。

聚集索引和二级索引如下图所示:

在这里插入图片描述
两者的区别是:

  • 聚集索引的叶子节点下挂的是这一行的数据
  • 二级索引的叶子节点下挂的是该字段值对应的主键值

所以引入下面的回表查询

select * from user where name = 'Arm'

主要看这个语句,它的查询条件不是聚集索引,但是又要查询全部字段。所以此时他需要先通过二级索引查询到主键,再通过主键回表查询

在这里插入图片描述

(其实这里也引出了后面的索引优化,怎么查询性能才比较高)

3.按字段个数

单列索引 & 联合索引

索引优化

1.SQL性能分析

一般来说,对于一个数据库表,查询是远高于增删改的,所以我们在说Mysql的性能分析(优化)时,关注的都是对查询的优化。
(1)profile命令
show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪里去了

首先查看mysql是否支持profile(输出yes即支持)

SELECT  @@have_profiling ;

默认情况是关闭的,通过以下命令开启

SET  profiling = 1;

然后就可以执行一系列的sql语句了,例如:

select * from tb_user;
select * from tb_user where id = 1;
select * from tb_user where name = 'Arm';
select count(*) from tb_sku;

接下来就可以通过命令查看了

-- 查看每一条SQL的耗时基本情况
show profiles;-- 查看指定query_id的SQL语句各个阶段的耗时情况
show profile  for  query query_id;

(2)explain 命令(很重要!)
获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序

命令如下(直接在查询语句前面加explain)

EXPLAIN   SELECT   字段列表   FROM   表名   WHERE  条件 ;

常见字段含义:

字段含义
idselect查询的序列号,表示查询中执行select子句或者是操作表的顺序
type表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、 index、all
key实际使用的索引
select_type表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)等
key_len表示索引中使用的字节数, 该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下, 长度越短越好 。

type字段很重要,再说一下它的类型:
type 字段就是描述了找到所需数据时使用的扫描方式是什么,常见扫描效率从高到低为(记住全表扫描性能肯定最差):

  • const(结果只有一条的主键或唯一索引扫描)。
  • eq_ref(唯一索引扫描);
  • ref(非唯一索引扫描);
  • range(索引范围扫描);
  • index(全索引扫描);
  • All(全表扫描);

2.索引失效

有多种情况索引会失效(注意这节判断sql语句是否索引失效的方法就是通过上面的explain语句

(1)索引列进行运算
常见的函数运算如count等会导致索引失效

解释:因为索引保存的是索引字段的原始值,而不是经过函数计算后的值

(2)对索引隐式类型转换
比如字符串类型字段使用时,不加引号(识别成整型),索引将失效(反过来不会失效)

解释:指路MySQL 的数据类型转换规则

(3)模糊查询
如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效

例如:

// 走索引
select * from t_user where name like '张%';
// 不走索引
select * from t_user where name like '%张';

解释:其实很好理解,因为索引 B+ 树是按照「索引值」有序排列存储的,只能根据前缀进行比较。如果是后缀的话只能走全表扫描了

(4)or连接
用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

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

注意:最左前缀法则中指的最左边的列,是指在查询时,联合索引的最左边的字段(即是第一个字段)必须存在。但与我们编写SQL时,条件编写的先后顺序无关

解释:在联合索引的情况下,数据是按照索引第一列排序,第一列数据相同时才会按照第二列排序

3.常见索引优化方法

(1)覆盖索引优化
覆盖索引是指 查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 ——避免了回表查询

举个例子:
比如对一个tb_user表中pro,age,sta字段进行联合索引

当执行

select * from tb_user where profession = '软件工程' and age = 31 and status = '0'

此时会导致回表查询

但是如果执行

select age,status from tb_user where profession = '软件工程' and age = 31 and status = '0'

则直接走二级索引,直接返回数据了

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

语法:

create index  idx_xxxx on table_name(column(n)) ;

(3) 索引最好为Not Null

参考链接:https://javaguide.cn/database/mysql/mysql-index.html

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

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

相关文章

【Linux】硬链接 和 软链接

为了方便用户访问文件,Linux提供了一种称为连接(link)的机制,可以将一个文件或目录与另一个文件或目录建立关联,从而实现多个路径指向同一个文件或目录的效果。 一、概述二、硬链接和软链接详解2.1 硬链接2.11 硬链接的…

如何在小程序中引入使用vant框架

一、vant框架 vantUI框架常用于移动端页面组件的基础库构建,为了让用户获得更趋向于原生的体验,它是一种相当不错的方案选择。 关于这个框架,它不仅有适用于移动端vue脚手架的版本,同时还存在可以兼容小程序开发的webapp版本。在…

你知道什么是生成对抗网络吗

生成对抗网络(GANs)是一种深度学习模型,已经显示出在许多生成相关任务中的卓越性能。最近几年,越来越多的研究人员将注意力集中于 GAN 的隐空间属性,并提出了许多利用这些属性进行语义图像编辑的方法。然而&#xff0c…

虚幻引擎(UE5)-大世界分区WorldPartition教程(二)

文章目录 前言一、OFPA怎么用二、OFPA怎么用总结 上一篇:虚幻引擎(UE5)-大世界分区WorldPartition教程(一) 前言 在UE4版本中中,Actor是保存在关卡文件中的,也就是说,如果要编辑关卡中的某些Actor,需要签出关卡文件进…

炫技亮点 Websocket集群解决方案汇总

文章目录 问题方案方案一:~~Session共享~~(不可行)方案二:负载均衡器(状态路由)方案三:广播机制(异步方式 - 建议)方案四:路由转发(同步方式&…

量子力学的起源和基本概念

亲爱的读者, 欢迎回到我们的量子力学系列文章。在我们的第一篇文章中,我们进行了量子力学的总体介绍。今天,我们将深入探讨量子力学的起源和一些基本概念。 量子力学的起源可以追溯到20世纪初,当时的科学家们遇到了一些古典物理…

【Java用法】windows10系统下修改jar中的文件并重新打包成jar文件然后运行

windows10系统下修改jar中的文件并重新打包成jar文件然后运行 一、背景描述二、操作步骤2.1 解压jar包2.2 修改配置文件2.3 重新打成jar包2.4 确认是否修改成功2.5 运行程序 一、背景描述 测试环境(Linux)的代码(jar包)拉取到本地…

Java之集合Collection

Collection接口有两个子接口:List(链表|线性表)和Set(集) ---|Collection: 单列集合---|List: 有存储顺序, 可重复---|ArrayList: 数组实现, 查找快, 增删慢由于是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以…

【深度学习 | CNN】“深入解析卷积神经网络与反卷积:从原理到应用的全面指南” (从一维、二维、三维讲解)

🤵‍♂️ 个人主页: @AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!🐱‍🏍 🙋‍♂️声明:本人目前大学就读于大二,研究兴趣方向人工智能&硬件(虽然硬件还没开始玩…

设计模式3:单例模式:JMM与volatile和synchronized的关系

本文目录 JMM简介Java 内部内存模型(The Internal Java Memory Model)硬件内存架构(Hardware Memory Architecture)弥合 Java 内存模型和硬件内存架构之间的差距(Bridging The Gap Between The Java Memory Model And The Hardware Memory Architecture)1.共享对象的可见性2.竞…

微软公布量子超级计算机路线图

光子盒研究院 6月22日,微软公布了三个重要的量子计算公告。首先,公司宣布它已经实现了通往量子超级计算机的六步路线图的第一个里程碑,并发表了一篇经同行评议的研究论文来证明这一成就。 这家科技巨头的第二项公告是将其人工智能&#xff08…

代理服务器之 squid、lvs、nginx、haproxy之间的区别

代理服务器之 squid、lvs、nginx、haproxy之间的区别 代理服务可简单的分为正向代理和反向代理 1、正向代理 正向代理服务器:squid 用于代理内部网络对 Internet 的连接请求(如 VPN/NAT),客户端指定代理服务器,并将本来要直接发送给目标 Web 服务器的 HT…