Mysql进阶(三)之索引篇

news2024/11/17 1:42:32

文章目录

  • 前言
  • 索引介绍
    • 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.coloradmin.cn/o/707496.html

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

相关文章

go-zero的配置及gorm、自定义返回等的引入以及扩展

工程维度(摘自官网) . ├── consumer ├── go.mod ├── internal │ └── model ├── job ├── pkg ├── restful ├── script └── service consumer: 队列消费服务internal: 工程内部可访问的公共模块job&a…

MMYOLO框架标注、训练、测试全流程(补充篇)

前言 MMYOLO框架是一个基于PyTorch和MMDetection的YOLO系列算法开源工具箱。MMYOLO定位为YOLO系列热门开源库以及工业应用核心库,MMYOLO框架Github项目地址支持的任务:目标检测、旋转目标检测支持的算法:YOLOv5、YOLOX、RTMDet、RTMDet-Rota…

使用 okhttp3库发送 get、post(json参数传递,form表单提交) java代码实现

OkHttp是一个开源的HTTP客户端,由Square公司开发。OkHttp3是OkHttp库的最新版本。它提供了一个简单而强大的API来处理网络通信。以下是OkHttp3库的一些主要特点: 与Android平台完全兼容:OkHttp3可以与标准的Java库一起使用,也可以…

【前端】导航栏html(ul+li)/css/js(jq)

引入jq <script src"https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> css代码 <style>ul {list-style: none;margin: 0;padding: 0;}li {cursor: pointer;}.color-white {color: #FFFFFF !important;background-color: rgb…

git 报错 fatal: Authentication failed的解决

git提交代码的时候&#xff0c;报错 remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for informa…

三个好基友Cookie、Session和Token

原创声明&#xff0c;转载请注明文章链接来源、作者信息 >三个好基友Cookie、Session和Token hello&#xff0c;我是索奇~ 精心写了一篇Cookie、Session和Token的 vivid 文章&#xff0c;并分享给大家 我们可以把Cookie、Token和Session看作是三个好基友&#xff0c;它们…

Linux中创建sftp用户并限制目录权限

注意两点&#xff1a; 一是禁止该用户通过ssh登录&#xff0c;二是不需要创建家目录。家目录简单来说&#xff0c;就是在/home下的用户命令&#xff0c;默认每个用户在/home中都是有与用户名一样的文件夹。 1.创建组 groupadd sftp 2. 创建用户 useradd -g sftp -s /sbin/…

Vue3 JSX 插槽、v-model 的用法以及 React JSX 的区别

前言 写这篇文章的初衷是&#xff0c;Vue3 JSX 部分与 React JSX 容易混淆&#xff0c;比如如本文所说的 slot & v-model&#xff0c; 如果你是第一次接触 JSX&#xff0c;可先阅读前面写过的 React & JSX 日常用法与基本原则 来对 JSX 有一个整体的认知以及比较两者间…

如何了解(海外抖音TiKToK)与国内抖音的区别以及介绍

一、海外抖音TK平台的优势 自从抖音在中国大受欢迎后&#xff0c;海外也推出了海外版抖音TK平台。尽管两者都是视频分享平台&#xff0c;但它们在一些方面具有明显的区别和独特的优势。下面将详细介绍海外抖音TK平台的优势以及与国内抖音的区别性。 优势&#xff1a; 1. 多元…

9-2 小波滤波器、去噪、增强、变换(matlab程序)

1.简述 小波去噪滤波算法是一种基于小波变换的滤波方法&#xff0c;它通过对信号进行小波变换来分解信号的频率分量&#xff0c;并根据信号的特点选择合适的阈值处理方法来去除噪声。该算法的主要思想是将信号分解成多个频率分量&#xff0c;根据信号的特点选择合适的阈值处理…

【IMX6ULL驱动开发学习】13.Pinctrl子系统与GPIO子系统

上一篇博客中&#xff0c;已经实现了设备树的添加 【IMX6ULL驱动开发学习】12.Linux驱动之设备树 这篇博客介绍Pinctrl子系统与GPIO子系统的使用 Pinctrl子系统参考文档&#xff1a; 内核文档链接&#xff1a;https://www.kernel.org/doc/Documentation/ 内核源码doc&#xff…

AD23 原理图选中元件在PCB中高亮显示

概述 项目需要&#xff0c;再次使用AD&#xff0c;在此做个笔录。 1、原理图界面 2、在原理图界面选中电容后&#xff0c;对应的PCB界面该电容高亮显示 3、总结 希望能帮助到有需要的攻城狮。

Linux查看日志常用操作整理

项目出现异常&#xff0c;要定位问题&#xff0c;查看日志是最常用的方法&#xff0c;在Linux系统查看一些日志文件&#xff0c;我们一般会使用tail、cat等命令&#xff0c;下面总结归纳一下这些常用的命令。 1、查看日志的方法 tail&#xff1a;tail命令应该是使用最多的&am…

探讨绿色照明与智能照明节能控制系统应用

张心志 安科瑞电气股份有限公司 上海嘉定 201801 【摘 要】随着社会经济的不断发展&#xff0c;人们对生活质量、环境品质越发重视。积极推广绿色智能照明&#xff0c;提高城市照明质量&#xff0c;对于改善人们居住环境意义重大。文章简要介绍了绿色照 明的基本要求、室内智…

互联网编程之简单邮箱发送程序

需求是使用Java写一个简单的邮箱发送程序。 注意需要到QQ邮箱的设置-账户中开启服务。 package org.example;import org.apache.commons.mail.Email; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail;public class Main {public …

ospf-interface-fsm-and-neighbor-fsm

/* Interface State Machine */ struct {int (*func) (struct ospf_interface *);int next_state; } ISM [OSPF_ISM_STATE_MAX][OSPF_ISM_EVEN

网络安全技术入门(1):简介

文章目录 1.前言2.什么是网络安全技术&#xff1f;3.列举一些常见的网络安全技术3.1 防火墙3.2 加密技术3.3 身份认证和访问控制3.4 恶意软件防护3.5 网络监控和日志管理3.6 威胁情报和漏洞管理3.7 安全培训和意识教育 4.网络安全研究的关键技术5.网络安全防护技术有哪些&#…

计算机网络 - 应用层http协议 - http报文格式介绍(1)

前言 本篇认识和理解应用层中的http协议&#xff0c;了解抓包工具并进行使用&#xff0c;认识请求报文与响应报文&#xff0c;了解报文中基本键值对意思例如&#xff1a;Set-Cookie, 状态码等&#xff0c;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#…

segement and remove-SAM一键清除物体(代码安装实战项目)

结果展示 去除图片中前景物体的步骤: 1.框选 2.分割 3.分离 4.去除 项目介绍 一键帮你剔除视频内的物体,现在只需要一句话。使用Meta的SAM技术,你现在可以让视频内任意物体消失! 特点 按照提示进行分割:只需输入“黑色狗”,您就可以将您的黑色狗分割出来; 修复图…

JAVA 初识序列化与反序列化

JAVA 初识序列化与反序列化 目录 JAVA 初识序列化与反序列化初识序列化与反序列化1 概述2 特点/应用场景3 涉及到的流对象4 代码实现序列化与反序列化4.1 步骤1&#xff1a;创建学生类Student4.2 步骤2&#xff1a;创建序列化测试类 5 测试报错NotSerializableException:6 测试…