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.pswp.cn/news/528974.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/528974.shtml
英文地址,請注明出處:http://en.pswp.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…