MySQL 索引,优化,回表,执行计划等相关总结学习

一、MySQL 执行流程

在这里插入图片描述

innoDB表引擎:默认的事务型引擎,最重要最广泛的存储引擎,性能非常优秀,数据村粗在共享表空间,可以通过配置分开,主键查询性能高于其他引擎

myISM表引擎:5.1版本前这个是默认的存储引擎,拥有全文索引、压缩、空间函数。不支持事务和行级锁,不支持安全恢复安全性低),存储在MYD和MYI两个文件中

innoDB和myISM的区别:InnoDB支持行锁,myISM支持表锁,myISM存储在MYD和MYI两个文件中,InnoDB存在共享表空间,InnoDB支持事务处理,myISM不支持

InnoDB 存储引擎:B+ 树索引的叶子节点保存数据本身
MyISAM 存储引擎:B+ 树索引的叶子节点保存数据的物理地址

二、索引分类

分类标准结果
数据结构B+tree索引、Hash索引、Full-text索引
物理存储聚簇索引(主键索引)、二级索引(辅助索引)
字段特性主键索引、唯一索引、普通索引、前缀索引
字段个数单列索引、联合索引

三、数据结构分类

索引类型innoDB 引擎MyISAM引擎Memory引擎
B+ 索引
Hash 索引×(不支持Hash索引,但在内存结构中有一个自适应hash索引)×
full-text 索引×

四、InnoDB 聚簇索引(主键索引)生成策略

  1. 根据主键ID 自动生成聚簇索引
  2. 没有主键 选择第一个不为 NULL 的唯一索引作为聚簇索引
  3. 以上均没有则会使用一个 6 个字节长整型的隐式字段 ROWID 构建聚簇索引(自增)

在建表时 InnoDB 存储引擎默认会创建一个主键索引,也就是聚簇索引,其它索引都属于二级索引

四、索引回表

定义:先通过索引扫描,再通过ID(主键)索引去取索引中未能提供的数据,即为回表

假设有表T 三个字段:id k name, 其中对 k 建立了单独索引
如果语句是 select * from T where id=200,即主键查询方式(聚集索引),则只需要搜索 ID 这棵 B+ 树,查询一表即可
如果语句是 select id, k from T where k=3,即普通索引查询方式,则只要搜索 k 索引树,这样的话查询一表即可。
如果语句是 select id, k , name from T where k=3,第一次通过普通索引查询方式得到 id 的值为 200,再到 id 索引树搜索一次(需要回表才能查到name这个数据)。这个过程称为回表。那如何避免回表,将k和name建成联合索引即可,当然,就算回表也会比没有建立索引快

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键(聚集索引)查询

如何避免回表:所以在查询时可以尽量用聚集索引来查(即主键查询)或根据业务需求建立的索引能满足索引查询字段。
但实际业务中很难建立一个索引就满足所有查询要求,所以,正常情况,回表也没事,只要能用到索引也能大大加快查询速度。

参考连接:
https://www.kancloud.cn/qq1014407916/huangwei123456/3019227

五、字段特性索引分类

类型说明
主键索引建立在主键字段上的索引,通常在创建表的时候一起创建,一张表最多只有一个主键索引,索引列的值不允许有空值
唯一索引建立在 UNIQUE 字段上的索引,一张表可以有多个唯一索引,索引列的值必须唯一,但是允许有空值
普通索引建立在普通字段上的索引,既不要求字段为主键,也不要求字段为 UNIQUE
前缀索引指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率。创建前缀索引的方式如下

前缀索引
在这里插入图片描述

六、联合索引

通过将多个字段组合成一个索引,该索引就被称为联合索引。
联合索引遵循最左匹配原则

假设创建了一个 (a, b, c) 三字段的联合索引,那么如果查询条件是以下这几种,就可以匹配上联合索引:

…where a=x;
…where a=x and b=y and c=z;
…where a=x and b=y;

假设
a字段 是全局有序的(1, 2, 2, 3, 4, 88,99,104,106),而 b 是全局是无序的(12,78,89,26,3,88,5,2)。因此,直接执行where b = 12 这种查询条件没有办法利用联合索引的,利用索引的前提是索引里的 key 是有序的。

在 a 相同的情况下 b 才是有序的,比如 a 等于 2 的时候,假设此时 b 的值为(78,89),这时就是有序的,这个有序状态是局部的,因此执行where a = 2 and b = 7是 a 和 b 字段能用到联合索引的,也就是联合索引生效了。

联合索引之范围查询:

场景一: select * from t_table where a > 1 and b = 12 联合索引(a, b)哪一个字段用到了联合索引的 B+Tree

为 a

场景二: select * from t_table where a >= 1 and b = 12 联合索引(a, b)哪一个字段用到了联合索引的 B+Tree

a,b 都用到了 但其中 b 索引只在 a=1 时使用

场景三: select * from t_table where a between 2 AND 88 AND b = 12,联合索引(a, b)哪一个字段用到了联合索引的 B+Tree

(a,b)联合索引

场景四: select* from t_user where a like ‘2%’ and b = 78,联合索引(name, age)哪一个字段用到了联合索引的 B+Tree

(a,b)联合索引

七、执行流程SQL优化-索引下推

执行器与存储引擎之间的交互过程

主键索引查询
全表扫描
索引下推
在这里插入图片描述

  1. 对于联合索引(a, b),在执行 select * from table where a > 1 and b = 12 语句时只有 a 字段能用到索引
    在联合索引的 B+Tree 找到第一个满足条件的主键值(id 为 2)后还需要判断其他条件是否满足(看 b 是否等于 12),那么是在联合索引里判断还是在主键索引判断

  2. MySQL 5.6 之前,只能从 id 2 (主键值)开始一个个回表,到主键索引上找出数据行再对比 b 字段值

  3. MySQL 5.6 引入的索引下推优化(index condition pushdown) 可以在联合索引遍历过程中对联合索引中包含的字段先做判断,直接过滤掉不满足条件的记录从而减少回表次数。

当查询语句的执行计划里,出现了 Extra 为 Using index condition 说明使用了索引下推优化

联合索引之索引区分度
由于建立联合索引时的字段顺序对索引效率也有很大影响,越靠前的字段被用于索引过滤的概率越高
建立联合索引时,要把区分度大的字段排在前面,这样区分度大的字段越有可能被更多的 SQL 使用到

区分度计算方式某个字段所有值的不同个数 除以 总行数

如果索引的区分度很小,假设字段的值分布比较均匀,那么无论搜索哪个值都可能得到一半的数据,在这种情况下还不如不要索引
因为 MySQL 有一个查询优化器,查询优化器发现某个值出现在表的数据行中的百分比(常用的百分比界线是 30%)很高时,一般会忽略索引进行全表扫描!

八、常见索引优化

前缀索引优化:使用前缀索引是为了减小索引字段大小。但前缀索引有一定的局限性,例如:
order by 就无法使用前缀索引
无法把前缀索引用作覆盖索引

覆盖索引优化:执行SQl以达到索引覆盖

主键索引设置自增:每插入一条新记录都是追加操作,不需要重新移动数据,如果我们使用非自增主键,会出现页分裂,页分裂可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率。

索引尽量设置为 NOT NULL:索引列存在 NULL 就会导致优化器在做索引选择的时候更加复杂,例如 count 会省略值为NULL 的行, NULL 值是一个没意义的值但会占用物理空间,至少会用 1字节

防止索引失效:通过执行计划分析 sql

九、索引失效

  1. 对索引使用左或者左右模糊匹配 (%xxx, %xxxxx%)
  2. 对索引使用函数 (例如点 length 的时候)
  3. 对索引进行表达式计算 (加减计算)
  4. 对索引隐式类型转换 (假设:设置了索引字段为 varchar 类型,但是写sql 时使用了 整形的写法,mysql 会通过默认的类型转换机制进行转换,即通过函数等方式,也就变相导致索引失效,但有时仅仅对值做了转换而没有对字段使用函数,那么即使做了潜在类型置换也不会导致索引失效)
    可以通过 select “10” > 9 的结果来知道MySQL 的数据类型转换规则是什么:
    如果规则是 MySQL 会将自动「字符串」转换成「数字」,就相当于 select 10 > 9,这个就是数字比较,所以结果应该是 1;
    如果规则是 MySQL 会将自动「数字」转换成「字符串」,就相当于 select “10” > “9”,这个是字符串比较,字符串比较大小是逐位从高位到低位逐个比较(按ascii码) ,那么"10"字符串相当于 “1”和“0”字符的组合,所以先是拿 “1” 字符和 “9” 字符比较,因为 “1” 字符比 “9” 字符小,所以结果应该是 0。
    实际上面的结果为 1,说明 MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较

例如

# 字段是字符串写为整形
select * from t_user where aaabc = 123456;
# 相当于
select * from t_user where CAST(aaabc AS signed int) = 123456;
# 失效
# 字段为整形 写为 字符串
select * from t_user where id = "1";
# 相当于
select * from t_user where id = CAST("1" AS signed int);
# 有效

参考文献:
https://zhuanlan.zhihu.com/p/471209432?utm_id=0

  1. 联合索引非最左匹配(见上方联合索引说明)
  2. WHERE 子句中的 OR:在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效

九、执行计划

执行计划中的参数可以参考如下

column意义
id序号,非Id
select_type查询类型
table查询表名
partitions匹配分区
type表示数据扫描类型,主要看此类型
processible_keys可能选择的索引
key实际选择的索引列,字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引
key_len索引长度
ref与索引做比较的列
rows预计要检索的行数
filtered查询过滤的行数百分比
Extra其他额外信息

type 扫描类型,执行效率从低到高为:

类型 (从低到高)意义
All全表扫描
index全索引扫描
range索引范围扫描
ref非唯一索引扫描
eq_ref唯一索引扫描
const结果只有一条的主键或唯一索引扫描

索引长度计算说明:
在这里插入图片描述

使用,在 查询SQL 前加入关键字 EXPLAIN 即可执行查询对应sql 的执行计划

count(*) 和 count(1)

count() 是一个聚合函数,函数的参数不仅可以是字段名也可以是其他任意表达式,该函数作用是统计符合查询条件的记录中函数指定的参数不为 NULL 的记录有多少个

如果表里有二级索引时,InnoDB 循环遍历的对象就不是聚簇索引,而是二级索引。

count(1) 相比 count(主键字段) 少一个步骤,就是不需要读取记录中的字段值,所以通常会说 count(1) 执行效率会比 count(主键字段) 高一点

性能排序: count(*) = count(1) > count(主键字段) > count(字段)

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

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

相关文章

第九节HarmonyOS 常用基础组件-Text

一、组件介绍 组件(Component)是界面搭建与显示的最小单位,HarmonyOS ArkUI声名式为开发者提供了丰富多样的UI组件,我们可以使用这些组件轻松的编写出更加丰富、漂亮的界面。 组件根据功能可以分为以下五大类:基础组件…

segment-anything安装教程

文章目录 一. segment-anything安装教程 一. segment-anything安装教程 官网安装说明:https://github.com/facebookresearch/segment-anything anaconda下新建一个环境 conda create -n sam python3.8激活新建的环境 conda activate sam更换conda镜像源 conda config --add ch…

Python过滤掉特定区域内的矩形框

Python过滤掉特定区域内的矩形框 前言前提条件相关介绍实验环境过滤掉特定区域内的矩形框方法一:直接法(for循环遍历)代码实现输出结果 方法二:列表推导式代码实现输出结果 前言 由于本人水平有限,难免出现错漏&#x…

Navicat Premium 16.3.3 Windows x64 Crack

增强您的表现。 Navicat 16 具有许多改进和功能,可以满足您的数据库开发需求。凭借 100 多项增强功能和全新界面,您可以探索构建、管理和维护数据库的新方法。构建时考虑到可用性。 Navicat 16 引入了许多 UI/UX 改进,以最大限度地提高您的效…

P4 链表的节点数统计与链表数据查找替换

目录 前言 01 链表的节点数统计 02 链表数据查找替换 2.1 残疾的数据查找 2.2 数据查找优化 前言 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C 》✨✨✨ 🔥 推荐专栏2: 《 Linux C应用编程(概念类)》✨…

Java集合(二)

1. Map 1.1 HashMap 和 Hashtable 的区别 线程是否安全: HashMap 是非线程安全的,Hashtable 是线程安全的,因为 Hashtable 内部的方法基本都经过synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!&…

C#,数值计算——插值和外推,谢别德(Shep)插值方法的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 谢别德插值方法 /// Object for Shepard interpolation using n points in dim dimensions. Call /// constructor once, then interp as many times as desired. /// &…

4.C转python

1.建立函数: def 函数名(形参): 函数体(记得写缩进) return 返回值(python中可以没有return) 2.调用函数: 函数名(实参) 实参和形参个数相等即可,类型不需要相同 其中接收返回值与C中的差不多 3.如果只是定义而不调用则函数不会执行 4.先定义函数,后调用 5.python中可以…

每天五分钟计算机视觉:ImageNet大赛的世界冠军AlexNet模型

AlexNet模型 2012 Imagenet 比赛第一&#xff0c;Top5准确度超出第二10% &#xff0c;它让人们认识到了深度学习技术的威力。比 LeNet更深&#xff0c;用多层小卷积层叠加替换大卷积层&#xff0c;就是说每一个卷积层的通道数小&#xff0c;不像LeNet一样每个卷积层的通道数很大…

记录华为云服务器(Linux 可视化 宝塔面板)-- 防火墙篇

文章目录 前言安装防火墙防火墙设置防火墙操作1.设置开机启动防火墙2.查看防火墙开放哪些端口3.重载防火墙配置&#xff08;修改配置后重新启动才生效&#xff09;4.查看防火墙状态5.开启防火墙6.关闭防火墙 若遇到无法开启查询已开放的端口查询端口是否开放&#xff08;80&…

Python爬虫-新能源汽车销量榜

前言 本文是该专栏的第11篇,后面会持续分享python爬虫案例干货,记得关注。 本文以懂车平台的新能源汽车销量榜单为例,获取各车型的销量排行榜单数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。 废话不多说,跟着笔者直接往下看正文详细内容。(附带…

电梯安全远程监控系统的主要作用和意义

电梯是现代城市生活中必不可少的交通工具&#xff0c;为了保证其安全可靠的运行&#xff0c;电梯运行监测系统应运而生。本文将介绍电梯安全远程监控的工作原理、重要性 一、电梯安全远程监控系统的作用   ◆实时监控和故障预警&#xff1a;电梯安全远程监控系统可以实时监测…

加强网站稳定性!学习如何进行高效压力测试!

前言 1、什么是压力测试&#xff1f; 软件压力测试是一种基本的质量保证行为&#xff0c;它是每个重要软件测试工作的一部分。 软件压力测试的基本思路很简单&#xff1a;不是在常规条件下运行手动或自动测试&#xff0c;而是在计算机数量较少或系统资源匮乏的条件下运行测试…

Pandas进阶:文本处理

引言 文本的主要两个类型是string和object。如果不特殊指定类型为string&#xff0c;文本类型一般为object。 文本的操作主要是通过访问器str 来实现的&#xff0c;功能十分强大&#xff0c;但使用前需要注意以下几点。 访问器只能对Series数据结构使用。 除了常规列变量df.c…

从0开始学习JavaScript--JavaScript 集成测试

JavaScript集成测试是确保整个应用程序组件协同工作的关键环节。通过模拟真实环境&#xff0c;集成测试能够发现不同组件之间的潜在问题&#xff0c;确保系统的稳定性和可靠性。本文将深入探讨JavaScript集成测试的核心概念、工具使用以及最佳实践&#xff0c;并通过丰富的示例…

1.2 Ubauntu 使用

一、完成VMware Tools安装 双击 VMwareTool 打开 Ubuntu 终端快捷键 AltControlT 切换汉语的快捷键是Alt空格 ls 打印出当前所在目录中所有文件和文件夹 cd 桌面 进入桌面文件夹 sudo ./vmware-install.pl 安装tool&#xff0c;输入之前设置的密码。 地址默认&#xff0c;按…

UI自动化测试工具有哪些优势?

UI自动化测试工具通过提高测试效率、覆盖率&#xff0c;减少测试时间和成本&#xff0c;以及支持持续集成等方式&#xff0c;为软件开发团队提供了一系列重要的优势&#xff0c;有助于提升软件质量和开发效率。 自动化执行&#xff1a;UI自动化测试工具可以模拟用户与应用程序的…

HarmonyOS脚手架:UI组件之文本和图片

前言 关于HarmonyOS脚手架&#xff0c;本篇是系列的第二篇&#xff0c;主要实现UI组件文本和图片的常见效果查看&#xff0c;本身功能特别的简单&#xff0c;其目的也是很明确&#xff0c;方便大家根据效果查看相关代码实现&#xff0c;可以很方便的进行复制使用&#xff0c;当…

TCP三次握手过程

什么是TCP tcp是一个面向连接的、可靠的、基于字节流的传输层通信协议 面向连接&#xff1a;TCP连接是一对一的&#xff0c;不能实现一对多或多对一&#xff0c;TCP在通信前要首先建立连接&#xff0c;连接成功后才能开始进行通信可靠的&#xff1a;TCP连接要保证通信过程的可靠…

iOS 版 ONLYOFFICE 文档 v7.4已更新!

iOS 版 ONLYOFFICE 文档 v7.4已更新 全新版本的免费 ONLYOFFICE 文档管理与编辑应用现已在 iOS 设备上推出。继续阅读以了解有关本次更新的信息&#xff0c;也可以在本文中找到应用的下载链接。 关于 ONLYOFFICE 文档 ONLYOFFICE 文档是一款适合手机与平板电脑的移动端应用套件…