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.mfbz.cn/a/209005.html

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

相关文章

inBuilder低代码平台新特性推荐-第十二期

各位CSDN的友友们,大家好~ 今天来给大家介绍一下inBuilder低代码平台社区版中特性推荐系列第十二期——新版本集成开发环境! 01 概述 编码规则定义规定了编号的生成格式,一条编码规则定义由基本信息和段列表组成:基本信息是对该编…

OCR原理解析

目录 1.概述 2.应用场景 3.发展历史 4.基于传统算法的OCR技术原理 4.1 图像预处理 4.1.1 灰度化 4.1.2 二值化 4.1.3 去噪 4.1.4 倾斜检测与校正 4.1.4.2 轮廓矫正 4.1.5 透视矫正 4.2 版面分析 4.2.1 连通域检测文本 4.2.2 MSER检测文本 4.3 字符切割 4.3.1 连…

视频后期特效处理软件 Motion 5 mac中文版

Motion mac是一款运动图形和视频合成软件,适用于Mac OS平台。 Motion mac软件特点 - 精美的效果:Motion提供了多种高质量的运动图形和视频效果,例如3D效果、烟雾效果、粒子效果等,方便用户制作出丰富多彩的视频和动画。 - 高效的工…

【力扣 面试题02.07链表相交】一种思路极其清晰的解法

力扣一单简单题,看完大佬的题解真是佩服得五体投地! 虽是一道简单题,当我吭哧吭哧写了几十行后,看到大佬仅仅几行直接秒掉,只能说算法的本质还是数学,数学逻辑思维真是太重要了,有时候真得慢慢去…

TZOJ 1429 小明A+B

答案&#xff1a; #include <stdio.h> int main() {int T0, A0, B0, sum0;scanf("%d", &T); //输入测试数据的组数while (T--) //循环T次{scanf("%d %d", &A, &B); //输入AB的值sum A B;if (sum > 100) //如果是三位数{…

使用 Go 构建高性能的命令行工具

命令行工具&#xff08;CLI&#xff09;在软件开发中扮演着重要的角色&#xff0c;尤其是在自动化工具、开发工具链和服务器管理等领域。Go 语言以其简洁性和高性能而闻名&#xff0c;非常适合用来创建强大且高效的 CLI 工具。本文将详细介绍如何使用 Go 语言来构建 CLI 应用&a…

基于hadoop下的hbase安装

简介 HBase是一个分布式的、面向列的开源数据库&#xff0c;该技术来源于Fay Chang所撰写的Google论文“Bigtable&#xff1a;一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统&#xff08;File System&#xff09;所提供的分布式数据存储一样&#xff0c;…

Python批量Git Pull,对文件夹批量进行Pull操作

效果展示 说明 本来是想写的完善一些&#xff0c;但由于是自用&#xff0c;所以写出来后发现已经解决了自己的问题&#xff0c;所有 2和3功能没有写。 执行的话&#xff0c;需要 cmd 之后 直接 Python BatchGitPull.py 运行下面代码即可。 里面同时涉及到其他Pyhon知识点(写给…

SSM项目实战-mapper实现

1、SysUserMapper.java package com.atguigu.schedule.mapper; import com.atguigu.schedule.pojo.SysUser; import org.springframework.stereotype.Repository; Repository public interface SysUserMapper {SysUser getSysUser(SysUser sysUser); }2、ScheduleMapper.java p…

“超越摩尔定律”,存内计算走在爆发的边缘

过去几十年来&#xff0c;在摩尔定律的推动下&#xff0c;处理器的性能有了显著提高。然而&#xff0c;传统的计算架构将数据的处理和存储分离开来&#xff0c;随着以数据为中心的计算&#xff08;如机器学习&#xff09;的发展&#xff0c;在这两个物理分离的单元之间传输数据…

3D云参观红色革命纪念馆允许更多人在线交流、体验

生活在和平年代的新一代青少年&#xff0c;可能对革命先烈英勇事迹难以有很深的体会&#xff0c;无法切实感受到中国共产党无畏牺牲、誓死保家卫国的红色精神&#xff0c;因此借助VR虚拟现实制作技术&#xff0c;让参观者们走近革命先烈中&#xff0c;感受老一辈无产阶级革命家…

YOLOv8 第Y7周 水果识别

1.创建文件夹&#xff1a; YOLOv8开源地址 -- ultralytics-main文件下载链接&#xff1a;GitHub - ultralytics/ultralytics: NEW - YOLOv8 &#x1f680; in PyTorch > ONNX > OpenVINO > CoreML > TFLite 其余文件由代码生成。 数据集下载地址&#xff1a;Frui…

CF1877 E. Autosynthesis 基环树dp

传送门:CF [前题提要]:一道基环树dp,但是题目有点绕,当时卡了我整整半天,到了第二天换了和清醒的脑子然后和别人讨论才整明白,故记录一下 题目很绕,故不再介绍. 首先对于这种下标和值有关系的题目.其实不难想到建图(CF上有大量这种 t r i c k trick trick),随便举个类似的题…

HarmonyOs 4 (一) 认识HarmonyOs

目录 一 HarmonyOs 背景1.1 发展时间线1.2 背景分析1.2.1 新场景1.2.2 新挑战1.2.3 鸿蒙生态迎接挑战 二 HarmonyOS简介2.1 OpenHarmony2.2 HarmonyOS Connect2.3 HarmonyOS Next**2.4 ArkTS &#xff08;重点掌握&#xff09;****2.5 ArkUI** 三 鸿蒙生态应用核心技术理念**3.…

Gavin Wood:财库保守主义偏离了初心,应探索 Fellowship 等更有效的资金部署机制

波卡创始人 Gavin Wood 博士最近接受了 The Kusamarian 的采访&#xff0c;分享了他的过往经历、对治理的看法&#xff0c;还聊到了 AI、以太坊、女巫攻击、财库等话题。本文整理自 PolkaWorld 对专访编译的部分内容&#xff0c;主要包含了 Gavin 对治理、财库提案、生态资金分…

re:Invent大会,亚马逊云科技为用户提供端到端的AI服务

11月末&#xff0c;若是你降落在拉斯维加斯麦卡伦国际机场&#xff0c;或许会在大厅里看到一排排AI企业和云厂商相关的夸张标语。走向出口的路上&#xff0c;你的身边会不断穿梭过穿着印有“AI21Lab”“Anthropic”等字样的AI企业员工。或许&#xff0c;你还会被机场工作人员主…

PyQt基础_014_对话框类控件QFileDialog

基本操作 import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import *class filedialogdemo(QWidget):def __init__(self, parentNone):super(filedialogdemo, self).__init__(parent)layout QVBoxLayout()self.btn QPushButton("…

【Linux】cp 命令使用

cp 命令 cp&#xff08;英文全拼&#xff1a;copy file&#xff09;命令主要用于复制文件或目录。 著者 由Torbjorn Granlund、David MacKenzie和Jim Meyering撰写。 语法 cp [选项]... [-T] 源文件 目标文件或&#xff1a;cp [选项]... 源文件... 目录或&#xff1a;cp [选…

SpringBoot 集成 ChatGPT,实战附源码

1 前言 在本文中&#xff0c;我们将探索在 Spring Boot 应用程序中调用 OpenAI ChatGPT API 的过程。我们的目标是开发一个 Spring Boot 应用程序&#xff0c;能够利用 OpenAI ChatGPT API 生成对给定提示的响应。 您可能熟悉 ChatGPT 中的术语“提示”。在 ChatGPT 或类似语…

UDS诊断服务

UDS诊断服务 什么是UDS&#xff1f; UDS – Unified diagnostic services (统一诊断服务) 俗称14229. 形象的说&#xff1a;就是使用一套仪器&#xff0c;对当前汽车出现的问题进行分析。而这套仪器与汽车交谈所使用的语言就是UDS&#xff08;不是唯一的方法&#xff09;。 …