mysql explain 执行计划 超简单入门介绍与sql案例以及常用sql优化方案

news2024/11/27 4:16:52

explain说明

EXPLAIN是MySQl必不可少的一个分析工具,主要用来测试sql语句的性能及对sql语句的优化,或者说模拟优化器执行SQL语句。 在select语句之前增加explain关键字,执行后MySQL就会返回执行计划的信息
而不是执行sql。但如果from中包含子查询,MySQL仍会执行该子查询,并把子查询的结果放入临时表中。
它显示了mysql如何使用索引来处理select语句以及连接表,可以帮助选择更好的索引和写出更优化的查询语句

创建几个个简单的表做关联用来演示

user表

DROP TABLE IF EXISTS `upms_user`;
CREATE TABLE `upms_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `username` varchar(64) DEFAULT NULL COMMENT '用户名',
  `password` varchar(255) DEFAULT NULL COMMENT '密码',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4;

role表

DROP TABLE IF EXISTS `upms_role`;
CREATE TABLE `upms_role` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `role_name` varchar(64) DEFAULT NULL COMMENT '角色名称',
  `role_code` varchar(64) DEFAULT NULL COMMENT '角色编码',
  `role_desc` varchar(255) DEFAULT NULL COMMENT '角色描述',
  `tenant_id` int(5) DEFAULT '1' COMMENT '租户id',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8mb4;

user_role表

DROP TABLE IF EXISTS `upms_user_role`;
CREATE TABLE `upms_user_role` (
  `user_id` int(11) NOT NULL COMMENT '用户ID',
  `role_id` int(11) NOT NULL COMMENT '角色ID',
  PRIMARY KEY (`user_id`,`role_id`),
  KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

执行一个简单关联查询查看explain 查看都有哪些列

EXPLAIN SELECT
*
FROM
upms_user USER
INNER JOIN upms_user_role urole ON USER .user_id = urole.user_id
INNER JOIN upms_role role ON role.role_id = urole.role_id

执行结果

在这里插入图片描述

可以看见一共以下列:

id: 选择标识符 select_type: 查询类型
table: 输出结果集的表
partitions: 匹配的分区
type: 表的连接类型
possible_keys: 查询时可能使用的索引
key: 实际使用的索引
key_len: 索引字段的长度
ref: 列与索引的比较
rows: 扫描出的行数 filtered: 按表条件过滤的行百分比
extra: 执行情况描述和说明

结合sql对每列进行详细说明

id列

id列的编号是select的序列号,有几个select就有几个id,并且id的顺序是按select出现的顺序增长的。
id越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行

id相同的情况下

一般都是直接关联查询,id相同从上往下执行
在这里插入图片描述

id不同的情况下

一般就是带有from 查询或者子查询等明确循序的sql,id越大,执行优先级越高

在这里插入图片描述

select type列,select type表示对应行是简单还是复杂的查询。

simple:简单查询。查询不包含子查询和union。

还是拿刚才的sql例子,执行后发现都是simple,因为没有子查询和union如下

在这里插入图片描述

primary:复杂查询中最外层的select

subquery:包含在select中的子查询

不在from子句中,实际测试在from中的也会被标记subquery

derived:包含在from子句中的子查询(实际)。MySQL会将结果存放在一个临时表中,也称为派生表。

实际测试在from中的也会被标记subquery*

在这里插入图片描述

union:在union关键字随后的selelct。

会先执行uinon 后面的select 语句然后结果再执行union 前面的select 结果最后汇总

在这里插入图片描述

table列

这一列表示explain的一行正在访问哪个表。
当from子句中有子查询时,table列是格式,表示当前查询依赖id=N的查询,于是先执行id=N的查询。
当有union时,UNION RESULT的table列的值为<union 1,2>,1和2表示参与union的select行id。

在这里插入图片描述

type列(重点,关系到是否用了索引以及索引类型,用来优化查询)

这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行对应的大概范围。 依次从最优到最差的分别为:system>const>eq_ref>ref>range>index>All
一般来说,得保证查询达到range级别,最好达到ref。
NULL:MySQL能够在优化阶段分解查询语句,在执行阶段用不着在访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需在执行时访问表

type 类型列举排序说明

主要有如下类型:
system
const
eq_ref
ref
range
index
All

这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行对应的大概范围。
依次从最优到最差的分别为:system>const>eq_ref>ref>range>index>All
一般来说,得保证查询达到range级别,最好达到ref。

const、system (其实可以认为是一个,system表示表里只有一行数据的时候的const)

用于primay key或unique key的所有列与常数比较时,所以表最多有一个匹配行,读取1次,速读较快。system 是const的特例,表中只有一行元素匹配时为system
在这里插入图片描述

这里直接用了主键去查所以是const,如果表里只有一条数据,那么就是system,unique key效果是一样的

eq_ref(一般都是带有关联查询且最多返回一条,情况很少,暂时忽略)

primay key或 unique key索引的所有部分被连接使用,最多只会返回一条符合条件的记录。这可能是const之外最好的联接类型,简单的select查询不会出现这种type

ref(常规长训场景最好达到此索引级别)

相比eq_ref,不适用唯一索引,而是使用普通索引或者唯一索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。 简单select查询,name是普通索引(非主键索引或唯一索引)

在这里插入图片描述

这种关联查询比较常见,基本上是关联用到了普通索引

range(比较常见,比如集合内,日期区间查询等)

范围扫描通常出现在in(), between,>,<,>=等操作中。使用一个索引来检索给定范围的行。
在这里插入图片描述
在这里插入图片描述

index(基本上是无条件查询,但是查询内容是索引)

index:扫描全表索引,通常比All快一些
在这里插入图片描述

all:(全表扫描,一般很可能意味着需要优化了)

在这里插入图片描述

上面的查询索引字段变为 即没用到索引,则走了全表扫描*

possible_keys列(不是一定准确的)

这一列显示select可能会使用哪些查询来查找。
在这里插入图片描述

key列(实际准确用到的)

这一列显示MySQL实际采用哪个索引对该表的访问。
如果没有使用索引,则改列为NULL

在这里插入图片描述

key_len列

这一列显示了mysql在索引里使用的字节数,通过这个值可以估算出具体使用了索引中的哪些列。

ref列

这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有: const(常量),字段名等
在这里插入图片描述

row列(读取并检测的行数,注意这个不是结果集的行数)

在这里插入图片描述

Extra列(额外信息)

包含内容如下:

Using index:使用覆盖索引(结果集的字段是索引,即select后的film_id)
Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导的范围
Using where:使用where语句来处理结果,查询的列未被索引覆盖
Using where:使用where语句来处理结果,查询的列未被索引覆盖
Using temporary:mysql需要创建一张临时表来处理查询。出现这种情况一般要进行优化,首先要想到是索引优化。

常用优化方法

1、选取最适用的字段属性

2、使用连接(JOIN)来代替子查询(Sub-Queries)

3、使用联合(UNION)来代替手动创建的临时表

索引何时应该使用

需创建索引的情况:
1.主键,自动建立唯一索引
2.频繁作为查询的条件的字段
3.查询中与其他表关联的字段存在外键关系
4.查询中排序的字段,排序字段若通过索引去访问将大大提高排序的速度
5.查询中统计或者分组字段 避免创建索引的情况:
1.数据唯一性差的字段不要使用索引 比如性别,只有两种可能数据。意味着索引的二叉树级别少,多是平级。这样的二叉树查找无异于全表扫描。
2.频繁更新的字段不要使用索引 比如登录次数,频繁变化导致索引也频繁变化,增大数据库工作量,降低效率。
3.字段不在where语句出现时不要添加索引 只有在where语句出现,mysql才会去使用索引
4.数据量少的表不要使用索引 使用了改善也不大 三、哪些sql能命中索引
1.前导模糊查询不能使用索引,如name like ‘%nowjava’ 2、Union、in、or可以命中索引,建议使用in。 3、负条件查询不能使用索引,可以优化为in查询,其中负条件有!=、<>、not in、not exists、not like等
4、联合索引最左前缀原则,又叫最左侧查询,如果在(a,b,c)三个字段上建立联合索引,那么它能够加快a|(a,b)|(a,b,c)三组的查询速度。
5、建立联合查询时,区分度最高的字段在最左边
6、如果建立了(a,b)联合索引,就不必再单独建立a索引。同理,如果建立了(a,b,c)索引就不必再建立a,(a,b)索引
7、存在非等号和等号混合判断条件时,在建索引时,要把等号条件的列前置 8、范围列可以用到索引,但是范围列后面的列无法用到索引。
索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引。范围条件有:<、<=、>、>=、between等。
9、把计算放到业务层而不是数据库层。在字段上计算不能命中索引, 10、强制类型转换会全表扫描,
如果phone字段是varcher类型,则下面的SQL不能命中索引。Select * from user where
phone=1380000000 11、更新十分频繁、数据区分度不高的字段上不宜建立索引。
更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能。
“性别”这种区分度不太大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似。
一般区分度在80%以上就可以建立索引。区分度可以使用count(distinct(列名))/count(
)来计算。
12、利用覆盖索引来进行查询操作,避免回表。
被查询的列,数据能从索引中取得,而不是通过定位符row-locator再到row上获取,即“被查询列要被所建的索引覆盖”,这能够加速度查询。
13、建立索引的列不能为null,使用not null约束及默认值 14、利用延迟关联或者子查询优化超多分页场景,
MySQL并不是跳过offset行,而是取offset+N行,然后放弃前offset行,返回N行,那当offset特别大的时候,效率非常低下,要么控制返回的总数,要么对超过特定阈值的页进行SQL改写。
15、业务上唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
16、超过三个表最好不要用join,需要join的字段,数据类型必须一致,多表关联查询时,保证被关联的字段需要有索引。
17、如果明确知道查询结果只要一条,limit 1能够提高效率,比如验证登录的时候。 18、Select语句务必指明字段名称
19、如果排序字段没有用到索引,就尽量少排序 20、尽量用union all 代替
union。Union需要将集合合并后在进行唯一性过滤操作,这会涉及到排序,大量的cpu运算,加大资源消耗及延迟,当然,使用union
all的前提条件是两个结果集没有重复数据。
*

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

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

相关文章

Ubuntu安装搜狗输入法

目前搜狗输入法已支持Ubuntu1604、1804、1910、2004、20101、添加中文语言支持&#xff0c;并使用fcitx输入法框架&#xff08;搜狗输入法基于fcitx&#xff09;打开 系统设置——区域和语言——管理已安装的语言——在“语言”tab下——点击“添加或删除语言”弹出“已安装语言…

RabbitMq相关面试题

文章目录消息队列有没有接触过&#xff1f; 简单介绍一下&#xff1f;消息中间件模式分类 &#xff1f;使用MQ有什么好处&#xff1f;MQ如何选型 &#xff1f;你们项目中用到过 MQ 吗&#xff1f;谈谈你对 MQ 的理解&#xff1f;MQ消费者消费消息的顺序一致性问题&#xff1f;R…

蓝桥杯-单片机类客观题真题解析

2017年第八届(国赛) 选项A 用于中断 选项B code :程序存储区(64KB) idata:固定指前面0x00-0xff的256个RAM,其中前128和data的128完全相同,只是因为访问的方式不同,是用类似C中的指针方式访问的。 data:固定指前面0x00-0x7f的128个RAM,可以直接读写的,速度最快,生…

如何降低输电线路在线监控摄像头的功耗呢?

输电线路视频/图像监测装置通过安装在线路杆塔上的摄像头&#xff0c;将线路走廊、通道、杆塔、绝缘子、导线、金具等的图像&#xff0c;经无线公网&#xff08;4G/3G&#xff09;传输到监控中心平台上&#xff0c;使管理者和运维人员通过办公电脑&#xff0c;就可实时掌握现场…

内存检测工具Dr.Memory在Windows上的使用

之前在https://blog.csdn.net/fengbingchun/article/details/51626705 中介绍过Dr.Memory&#xff0c;那时在Windows上还不支持x64&#xff0c;最新的版本对x64已有了支持&#xff0c;这里再总结下。 Dr.Memory源码地址https://github.com/DynamoRIO/drmemory&#xff0c;最新发…

计算机网络概念——应用层email协议

1. email的工作方式。电子邮件中有四个重要的组成部分&#xff1a;邮件服务器&#xff08;电子邮件体系结构的核心&#xff0c;为其用户提供邮箱服务&#xff08;管理、维护用户报文的服务&#xff09;&#xff0c;并起到邮件服务器间相互通信的作用&#xff09;、用户代理&…

apisix 初体验

文章目录前言一、参考资料二、安装1.安装依赖2.安装apisix 2.53.apisix dashboard三、小试牛刀3.1 上游&#xff08;upstream&#xff09;3.2 路由&#xff08;route&#xff09;四、遇到的问题前言 APISIX 是一个微服务API网关&#xff0c;具有高性能、可扩展性等优点。它基于…

JavaEE15-Spring Boot统一功能处理

目录 1.统一用户登录权限效验 1.1.最初用户登录验证 1.2.Spring AOP用户统一登录验证的问题 1.3.Spring拦截器 1.3.1.创建自定义拦截器&#xff0c;实现 HandlerInterceptor 接口并重写 preHandle&#xff08;执行具体方法之前的预处理&#xff09;方法 1.3.2.将自定义拦…

2023养老展,CBIAIE第十届中国北京国际老年产业博览会

8月招商季&#xff0c;第十届中国&#xff08;北京&#xff09;国际老年产业博览会再次盛大举办&#xff1b; CBIAIE北京国际老年产业博览会位域优势&#xff1a; ——北京&#xff0c;中国首都&#xff0c;世界一线城市&#xff0c;地处中国北部、华北平原北部&#xff0c;东…

安装PhpStorm2020.3

1、卸载旧软件 如果已安装软件&#xff0c;先打开文件安装目录&#xff0c;找到Uninstall.exe点击卸载 删除.jetbrains目录 点击软件“PhpStorm-2020.3.exe”安装 打开软件 打开一个新建的空文件夹&#xff0c;预加载 将BetterIntelliJ.zip拖动到idea的编辑区域 然后…

Python爬虫之Scrapy框架系列(13)——实战ZH小说爬取数据入MySql数据库

目录&#xff1a;1 数据持久化存储&#xff0c;写入Mysql数据库①定义结构化字段&#xff1a;②重新编写爬虫文件&#xff1a;③编写管道文件&#xff1a;④辅助配置&#xff08;修改settings.py文件&#xff09;&#xff1a;⑤navicat创库建表&#xff1a;⑥ 效果如下&#xf…

Pspice-介绍

根据B站&#xff1a;【PSpice简单入门教程】 https://www.bilibili.com/video/BV19Z4y157tA/?share_sourcecopy_web&vd_sourcec20b4c8e2a733bf3f410c58538211a7f&#xff08;一&#xff09;原理图仿真的原因仿真节省经费&#xff0c;比如蒙特卡罗分析&#xff0c;最坏情况…

R语言raster包批量拼接、融合大量栅格图像

本文介绍基于R语言中的raster包&#xff0c;遍历文件夹&#xff0c;读取文件夹下的大量栅格遥感影像&#xff0c;并逐一对每一景栅格图像加以拼接、融合&#xff0c;使得全部栅格遥感影像拼接为完整的一景图像的方法。 其中&#xff0c;本文是用R语言来进行操作的&#xff1b;如…

【MongoDB】多级嵌套数组的操作 含Mongo Shell 和 MongoTemplate的增删改细节

文章目录1.前言2.数据准备3.Mongo Shell操作实践3.1.第一层数组操作3.1.1.新增元素3.1.2.修改元素3.1.2.1.批量修改元素中的坑3.1.3.使用$[<identifier>]做批量修改3.1.4.移除元素3.2.第二层数组操作3.2.1.新增与移除元素3.2.2.修改元素中的字段值3.2.2.1.易错点4.Mongo …

基于yolo的小球位置实时检测

基于yolo的小球位置实时检测 Yolo安装 操作系统&#xff1a;ubuntu 安装cuda和opencv git clone https://github.com/pjreddie/darknet.git cd darknet 修改Makefile文件&#xff0c;使GPU1&#xff0c;OPENCV1 make 2. 数据集处理 2.1 制作数据集 将小球放在摄像头前…

分布式高级篇2 —— 商城业务 (1)

一、商品上架 一、商品上架1、sku 在 ES 中存储模型分析2、nested 嵌套类型3、商品上架业务代码&#xff08;1&#xff09;构建 sku 基本属性&#xff08;2&#xff09;构造 sku 检索属性&#xff08;3&#xff09;远程调用查询库存&#xff08;4&#xff09; 远程调用上架接口…

【干货】Python:time库的用法

【干货】Python&#xff1a;time库的用法1. time库概述2. time库的运用2.1 时间处理2.1.1 time()2.1.2 gmtime()2.1.3 localtime()2.1.4 ctime()2.2 时间格式化2.2.1 mktime()2.2.2 strftime()2.2.3 strptime()2.3 计时3. 习题4. 本文代码编译环境及版本5. 更新日志6. 参考1. t…

【CSS面试题】2023前端最新版css模块,高频15问

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;博主收集的CSS面试题 目录 一、CSS必备面试题 1.CSS3新特性 2.CSS实现元素两个盒子垂…

内网穿透-frp

frp的作用 1.利用处于内网或防火墙后的机器&#xff0c;对外网环境提供 http 或 https 服务。 2.对于 http, https 服务支持基于域名的虚拟主机&#xff0c;支持自定义域名绑定&#xff0c;使多个域名可以共用一个80端口。 3.利用处于内网或防火墙后的机器&#xff0c;对外网环…

【Python】Python学习笔记(二)基本输入输出

Python娘来源&#xff1a;https://next.rikunabi.com/tech/docs/ct_s03600.jsp?p002412 目录print()函数不进行自动换行的print()函数打印输出多个字符串只进行换行input()函数使用format方法格式化字符串字符串与数值转换字符串转换为数值数值转换为字符串总结参考资料print(…