sql in转换为join_同一个SQL语句,为啥性能差异咋就这么大呢?(1分钟系列)

《数据库允许空值,往往是悲剧的开始》一文通过explain来分析SQL的执行计划,来分析null对索引命中情况的影响,有不少朋友留言,问explain结果中的type字段,ref,ALL等不一样的值究竟是什么含义。

今天花1分钟简单说下,常见的type结果及代表的含义,并且通过同一个SQL语句的性能差异,说明建对索引多么重要。

explain结果中的type字段代表什么意思?

d36d62cfa0be11c6592b611a1df0c0ed.png

MySQL的官网解释非常简洁,只用了3个单词:连接类型(the join type)。它描述了找到所需数据使用的扫描方式。

最为常见的扫描方式有:

  • system:系统表,少量数据,往往不需要进行磁盘IO;

  • const:常量连接;

  • eq_ref:主键索引(primary key)或者非空唯一索引(unique not null)等值扫描;

  • ref:非主键非唯一索引等值扫描;

  • range:范围扫描;

  • index:索引树扫描;

  • ALL:全表扫描(full table scan);

画外音:这些是最常见的,大家去explain自己工作中的SQL语句,95%都是上面这些类型。

上面各类扫描方式由快到慢

system > const > eq_ref > ref > range > index > ALL

下面一一举例说明。

一、system

81011de92b5cde0f599ff2c600b8927a.png

explain select * from mysql.time_zone;

上例中,从系统库mysql的系统表time_zone里查询数据,扫码类型为system,这些数据已经加载到内存里,不需要进行磁盘IO。

这类扫描是速度最快的。

03bbc51fcfeb317188df5e5ec03a969e.png

explain select * from (select * from user where id=1) tmp;

再举一个例子,内层嵌套(const)返回了一个临时表,外层嵌套从临时表查询,其扫描类型也是system,也不需要走磁盘IO,速度超快。

二、const

数据准备:

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'shenjian');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

488da62246e3ee73386b495cc5702686.png

const扫描的条件为:

(1)命中主键(primary key)或者唯一(unique)索引;

(2)被连接的部分是一个常量(const)值;

explain select * from user where id=1;

如上例,id是PK,连接部分是常量1。

画外音:别搞什么类型转换的幺蛾子。

这类扫描效率极高,返回数据量少,速度非常快。

三、eq_ref

数据准备:

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'shenjian');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

create table user_ex (

id int primary key,

age int

)engine=innodb;

insert into user_ex values(1,18);

insert into user_ex values(2,20);

insert into user_ex values(3,30);

insert into user_ex values(4,40);

insert into user_ex values(5,50);

d36d62cfa0be11c6592b611a1df0c0ed.png

eq_ref扫描的条件为,对于前表的每一行(row),后表只有一行被扫描。

再细化一点:

(1)join查询;

(2)命中主键(primary key)或者非空唯一(unique not null)索引;

(3)等值连接;

explain select * from user,user_ex where user.id=user_ex.id;

如上例,id是主键,该join查询为eq_ref扫描。

这类扫描的速度也异常之快。

四、ref

数据准备:

create table user (

id int,

name varchar(20) ,

index(id)

)engine=innodb;

insert into user values(1,'shenjian');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

create table user_ex (

id int,

age int,

index(id)

)engine=innodb;

insert into user_ex values(1,18);

insert into user_ex values(2,20);

insert into user_ex values(3,30);

insert into user_ex values(4,40);

insert into user_ex values(5,50);

43ad90cd70e03b6c9aa2cf06e0c514cc.png

如果把上例eq_ref案例中的主键索引,改为普通非唯一(non unique)索引。

explain select * from user,user_ex where user.id=user_ex.id;

就由eq_ref降级为了ref,此时对于前表的每一行(row),后表可能有多于一行的数据被扫描。

8e434fe670978d3f6cd72775124c6b63.png

explain select * from user where id=1;

当id改为普通非唯一索引后,常量的连接查询,也由const降级为了ref,因为也可能有多于一行的数据被扫描。

ref扫描,可能出现在join里,也可能出现在单表普通索引里,每一次匹配可能有多行数据返回,虽然它比eq_ref要慢,但它仍然是一个很快的join类型。

五、range

数据准备:

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'shenjian');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

insert into user values(4,'wangwu');

insert into user values(5,'zhaoliu');

ab4490088ba833eae5a7fc83613d6605.png

range扫描就比较好理解了,它是索引上的范围查询,它会在索引上扫码特定范围内的值。

explain select * from user where id between 1 and 4;

explain select * from user where idin(1,2,3);

explain select * from user where id>3;

像上例中的between,in,>都是典型的范围(range)查询。

画外音:必须是索引,否则不能批量"跳过"。

六、index

6676c15985d12d77fab97b09402a4703.png

index类型,需要扫描索引上的全部数据。

explain count (*) from user;

如上例,id是主键,该count查询需要通过扫描索引上的全部数据来计数。

画外音:此表为InnoDB引擎。

它仅比全表扫描快一点。

七、ALL

数据准备:

create table user (

id int,

name varchar(20)

)engine=innodb;

insert into user values(1,'shenjian');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

create table user_ex (

id int,

age int

)engine=innodb;

insert into user_ex values(1,18);

insert into user_ex values(2,20);

insert into user_ex values(3,30);

insert into user_ex values(4,40);

insert into user_ex values(5,50);

b7d1441c8efd9c30529b1a918582254c.png

explain select * from user,user_ex where user.id=user_ex.id;

如果id上不建索引,对于前表的每一行(row),后表都要被全表扫描。

今天这篇文章中,这个相同的join语句出现了三次:

(1)扫描类型为eq_ref,此时id为主键;

(2)扫描类型为ref,此时id为非唯一普通索引;

(3)扫描类型为ALL,全表扫描,此时id上无索引;

有此可见,建立正确的索引,对数据库性能的提升是多么重要。

另外,《类型转换带来的大坑》中,也提到不正确的SQL语句,可能导致全表扫描。

全表扫描代价极大,性能很低,是应当极力避免的,通过explain分析SQL语句,非常有必要。

总结

(1)explain结果中的type字段,表示(广义)连接类型,它描述了找到所需数据使用的扫描方式;

(2)常见的扫描类型有:

system>const>eq_ref>ref>range>index>ALL

其扫描速度由快到慢;

(3)各类扫描类型的要点是:

  • system最快:不进行磁盘IO

  • const:PK或者unique上的等值查询

  • eq_ref:PK或者unique上的join查询,等值匹配,对于前表的每一行(row),后表只有一行命中

  • ref:非唯一索引,等值匹配,可能有多行命中

  • range:索引上的范围扫描,例如:between/in/>

  • index:索引上的全集扫描,例如:InnoDB的count

  • ALL最慢:全表扫描(full table scan)

(4)建立正确的索引(index),非常重要;

(5)使用explain了解并优化执行计划,非常重要;

思路比结论重要,希望大家有收获。

画外音:本文测试于MySQL5.6。

43eff987fb30d194128441fe9351604f.png

架构师之路-分享技术思路

相关推荐:

《缓冲池(buffer pool),这次彻底懂了!!!》

《写缓冲(change buffer),这次彻底懂了!!!》

《两类非常隐蔽的全表扫描 | 1分钟系列》

《MyISAM与InnoDB的索引差异 | 1分钟系列》

《数据库允许null,悲剧的开始 | 1分钟系列》

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

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

相关文章

java rmi接口 超时设置_Spring RMI客户端读超时设置 | 学步园

标准Java的RMI设置我所知道的有三种方式,其中第1、2种不区分框架均适用,但影响整个JVM级别的RMI服务1. 启动时设置sun.rmi.transport.tcp.responseTimeout,单位是毫秒java -Dsun.rmi.transport.tcp.responseTimeout502.在应用程序中设置环境变…

python黑客库长安十二时辰 更新_【Python成长之路】python 从零学爬虫 -- 没时间看《长安十二时辰》电视剧怎么办?直接爬取所有剧情吧!...

【写在前面】最近大火的《长安十二时辰》真的是好看,算的是良心网剧了。但是由于平时工作时间较长,经常无法准时追剧,并且又因为不想见到元裁那对挨千刀的(作为演员,演技是值得肯定的,角色演绎的让人看的心烦)。因此就…

java字符串笔试题_五道Java常见笔试题及答案汇总

1、String和StringBuffer的区别?答:Java平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行…

遥感原理与应用孙家炳_2.2遥感应用模型

章节概览遥感应用模型是遥感的一种定量化手段,通常在遥感领域有一个更广为人知的名词——定量遥感。但是定量遥感是一种方法模型而非技术手段,随着科学的发展,热门越来越体会到定量遥感的必要性。定量遥感的应用是十分广泛的,也是…

python升级命令debian_debian python 2.7.11 升级

首先下载源tar包可利用linux自带下载工具wget下载,如下所示:下载完成后到下载目录下,解压tar -zxvf Python-2.7.11.tgz进入解压缩后的文件夹cdPython-2.7.11在编译前先在/wp-content/local建一个文件夹python27(作为python的安装路径&#xf…

mysql必学十大必会_MYSQL 学习(一)--启蒙篇《MYSQL必知必会》

MYSQL必知必会一. DDL 数据定义语言Data Definition Language 是指CREATE,ALTER和DROP语句。DDL允许添加/修改/删除包含数据的逻辑结构,或允许用户访问/维护数据(数据库,表,键,视图......)的逻辑结构。DDL是关于“元数…

python连接wifi_python 自动重连wifi windows的方法

如下所示:# codingutf-8import urllib2import urllibfrom cookielib import CookieJarimport osimport reimport timeclass ConnectWeb(object):def __init__(self):self.cookiejarinmemory CookieJar()self.opener urllib2.build_opener(urllib2.HTTPCookieProce…

java for新循环_Java 8 新语法习惯 (for 循环的函数替代方案)

我们看这样一个示例public class ForDemo {public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println("Get set...");for (int i 0; i < 4; i) {System.out.println(i"...");}}}测试结果Get set...0...1...2...…

喜马拉雅 xm文件转m4a_喜马拉雅电台、课程语音如何转成文字?

今天看了一篇文章“AI面前人类一败涂地”就是说了AI的发展让所有的事情几乎都可以实现科技化&#xff0c;无需人工操作&#xff0c;工作效率还比人工要高很多。这样说来的确是这样。语音转换也是其中一门技术&#xff0c;人们现在对于语音的交流很多&#xff0c;比如社交软件的…

java url特殊字符转义字符_URL中包含有特殊字符,进行转义

String temp URLEncoder.encode(json);URL中的特殊字符有些符号在URL中是不能直接传递的&#xff0c;如果要在URL中传递这些特殊符号&#xff0c;那么就要使用他们的编码了。编码的格式为&#xff1a;%加字符的ASCII码&#xff0c;即一个百分号%&#xff0c;后面跟对应字符的A…

java 多重注解_Java注解-元数据、注解分类、内置注解和自定义注解

大家好&#xff0c;我是乐字节的小乐&#xff0c;上次说过了Java多态的6大特性|乐字节&#xff0c;接下来我们来看看Java编程里的注解。Java注解有以下几个知识点&#xff1a;元数据注解的分类内置注解自定义注解注解处理器Servlet3.0本文先介绍前面4个知识点&#xff1a;元数据…

python getattr函数_Python中的getattr()函数详解

在计算机编程中&#xff0c;自省是指这种能力&#xff1a;检查某些事物以确定它是什么、它知道什么以及它能做什么。自省向程序员提供了极大的灵活性和控制力。自省(introspection)&#xff0c;在计算机编程领域里&#xff0c;是指在运行时来判断一个对象的类型的能力。它是Pyt…

ie8不兼容java项目_常见IE8兼容性问题及解决

1、css3媒体查询IE8不支持媒体查询解决&#xff1a;respond.js&#xff0c;在页面中所有css文件的引用位置之后引用Respond.js2、HTML5新标签IE8不支持H5新标签解决&#xff1a;html5shiv.js&#xff0c;在页面中引用html5shiv.js文件。必须添加在页面的元素内&#xff0c;因为…

python对图像二值化_python如何二值化图像

在python中二值化图像的方法&#xff1a;首先将图片转化为灰色图像&#xff1b;然后自定义灰度界限&#xff1b;最后输入“photoImg.point(table,1)”命令(table为自己创建的数组名)即可二值化图像。# 图片二值化代码如下&#xff1a;from PIL import Imageimg Image.open(tes…

Java快速提升_java快速复习 一 基础语法

最近看很多算法书&#xff0c;比较不错的有不少都是java语言描述&#xff0c;所以用一天时间快速研究并整理java &#xff0c;参考资料&#xff1a;java入门经典Call this file "Example2.java".class Example2 {public static void main(String args[]) {int a&…

酷狗音乐linux版_酷狗音乐概念版APP内测获用户好评:极简化,更高级

这两天在网上冲浪的时候&#xff0c;发现不少网友都在安利一个叫做“酷狗音乐概念版”的APP&#xff0c;难道是酷狗又在闷声搞大事了&#xff1f;搜了一下发现&#xff0c;原来是酷狗音乐概念版APP已经开始进入内测阶段&#xff0c;尝试着下载使用&#xff0c;果然发现“更酷更…

java 计算器类图_多态计算器(封装、继承、多态、简单工厂)

一.封装向对象程序设计中&#xff0c;一个非常重要的技术便是封装&#xff0c;也就是把客观事物封装成抽象的类&#xff0c;并且类可以把自己的数据和方法只让可信的类或者对象操作&#xff0c;对不可信的进行信息隐藏。这样做的好处在于可以使类内部的具体实现透明化&#xff…

图书管理系统 java 源码_[源码和文档分享]基于C语言和SQL SERVER数据库实现的图书管理系统...

摘 要本文根据《数据库应用系统设计》课程要求而做。选择图书馆管理系统设计与开发是因为觉得图书馆管理系统对我们的帮助很大&#xff0c;并且经常去图书馆&#xff0c;对图书馆的大部分功能及流程还是比较了解&#xff0c;而且现在有些地方可能还不够完善。这次课程设计目标是…

java useragent 360 遨游 火狐_各种浏览器UserAgent一览表(桌面+移动)

桌面IE而IE各个版本典型的userAgent如下&#xff1a;Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)其中&#x…

sql server 修改字段不能为空_SQL-SQL介绍

一SQL 介绍SQL&#xff08;Structured Query Language&#xff09;,语义是结构化语言&#xff0c; 是一门 ANSI 的标准计算机语言&#xff0c;用来访问和操作数据库系统&#xff1b;二 数据库介绍2.1 数据库我们已经知道了SQL是操作数据库的语言&#xff0c;那么数据库是什么&a…