亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MySQL之Explain詳解

 更新時間:2023年04月06日 09:00:57   作者:程序員句號  
使用Explain關(guān)鍵字可以模擬優(yōu)化器執(zhí)行SQL語句,分析你的查詢語句或是結(jié)構(gòu)的性能瓶頸,感興趣的的同學(xué)可以參考閱讀

Explain工具介紹

使用Explain關(guān)鍵字可以模擬優(yōu)化器執(zhí)行SQL語句,分析你的查詢語句或是結(jié)構(gòu)的性能瓶頸。在select語句之前增加explain關(guān)鍵字,Mysql會在查詢上設(shè)置一個標(biāo)記,執(zhí)行查詢會返回執(zhí)行計劃的信息,而不是執(zhí)行這條SQL
注意:如果from中包含子查詢,仍會執(zhí)行該子查詢,將結(jié)構(gòu)放入臨時表中

示例代碼

DROP TABLE IF EXISTS `actor`; 
CREATE TABLE `actor` (
  `id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `actor` (`id`, `name`, `update_time`) VALUES (1,'a','2017-12-22 15:27:18'), (2,'b','2017-12-22 15:27:18'), (3,'c','2017-12-22 15:27:18');

DROP TABLE IF EXISTS `film`;
CREATE TABLE `film` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `film` (`id`, `name`) VALUES (3,'film0'),(1,'film1'),(2,'film2');

DROP TABLE IF EXISTS `film_actor`;
CREATE TABLE `film_actor` (
  `id` int(11) NOT NULL,
  `film_id` int(11) NOT NULL,
  `actor_id` int(11) NOT NULL,
  `remark` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_film_actor_id` (`film_id`,`actor_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `film_actor` (`id`, `film_id`, `actor_id`) VALUES (1,1,1),(2,1,2),(3,2,1);

explain select * from actor;

在查詢中的每個表都會輸出一行,如果有兩個表通過join連接查詢,那么會輸出兩行

explain兩個變種 explain extended

會在explain的基礎(chǔ)上額外提供一些查詢優(yōu)化的信息(5.7自動加上了,不需要這個命令了)緊隨其后通過shouw warnings命令可以得到優(yōu)化后的查詢語句,從而看出優(yōu)化器優(yōu)化了什么。額外還有filtered列,是一個半分比的值。rows * filtered/100 可以估算出將要和explain中前一個表進(jìn)行連接的行數(shù)。

explain partitions

相比explain多了個partitions字段(5.7以后,explain默認(rèn)有了),如果查詢時基于分區(qū)表的話,會顯示查詢將訪問的分區(qū)

explain中的列

接下來我們將展示 explain 中每個列的信息。

id列

id列的編號是select的序列號,有幾個select就有幾個id,并且id的順序是按select出現(xiàn)的順序增長的。
id列值越大優(yōu)先級越高,id相同則是從上往下執(zhí)行,id為NULL最后執(zhí)行

select_type列

select_type表示對應(yīng)行是簡單還是復(fù)雜查詢

1.simple:簡單查詢,不包含子查詢和union

2.primary:復(fù)雜查詢中最外層的select

3.subquery:包含在select中的子查詢(不在from子句中)

4.derived:包含在from自居中的子查詢,MySQL會將結(jié)果存放在一個臨時表中,也稱為派生表

mysql> set session optimizer_switch=‘derived_merge=off’; #關(guān)閉mysql5.7新特性對衍生表的合并優(yōu)化

mysql> explain select (select 1 from actor where id = 1) from (select * from film where

id = 1) der;

5.union:在union中的第二個和隨后的select

table列

這一列表示explain的一行正在訪問哪個表
當(dāng)from子句中有子查詢時,table列時格式,表示當(dāng)前查詢依賴id=N的查詢,于是先執(zhí)行id=N的查詢
當(dāng)有union時,union result的table列的值為<union,1,2> ,1和1表示參與union的select行id。

type列

這一列表示關(guān)聯(lián)類型或訪問類型,即MySQL決定如何查找表中的行,查找數(shù)據(jù)行記錄的大概范圍。
依次從最優(yōu)到最差分別為:system > const > eq_ref > ref > range > index >ALL

一般來說得保證查詢達(dá)到range級別,最大達(dá)到ref

  • NULL:mysql能夠在優(yōu)化階段分解查詢語句,在執(zhí)行階段用不著訪問表或索引。例如:在索引列中取最小值,可以單獨查找索引來完成,不需要在執(zhí)行時訪問表

  • const,system:mysql能對查詢的某部分進(jìn)行優(yōu)化并將其轉(zhuǎn)換成一個常量(可以看show warnings的結(jié)果)。用于primary key 或 unique key的所有列與常數(shù)比較時,所以表最多有一個匹配行,讀取一次,速度比較快。system時const的特例,表里只有一條元組匹配時為system。(意思就是system只有在數(shù)據(jù)找到一條的情況下出現(xiàn))
 explain extended select * from (select * from film where id =1) tmp;

  • eq_ref:primary key或 unique key 索引所在部分被連接使用,最多只會返回一條符合條件的記錄。這可能時在const之外最好的聯(lián)接類型了,簡單的select查詢不會出現(xiàn)這種type
explain select * from film_actor left join film on film_actor.film_id = film.id;

  • ref:相比eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前綴,索引要和某個值相比較,可能會找到多個符合條件的行(hang)。
1. 簡單 select 查詢,name是普通索引(非唯一索引)
mysql> explain select * from film where name = 'film1';

關(guān)聯(lián)表查詢,idx_film_actor_id是film_id和actor_id的聯(lián)合索引,這里使用到了film_actor的左邊前綴film_id部分。
mysql> explain select film_id from film left join film_actor on film.id = film_actor.film_id;

  • range:范圍掃描通常出現(xiàn)在in(),between,>,<,>=等操作中,使用一個索引來檢索給定范圍的行。
mysql> explain select * from actor where id > 1;

  • index:掃描全索引就能拿到結(jié)果,一般是掃描某個二級索引,這種掃描不會從索引樹根節(jié)點開始快速查找,而是直接對二級索引的葉子節(jié)點遍歷和掃描,速度還是比較慢的,這種查詢一般為使用覆蓋索引,二級索引一般比較小,所以這種通常比ALL快一些。
explain select * from film;

為什么這里是走的idx_name這個索引?沒有走主鍵索引?
因為MySQL底層有一套判斷使用哪個索引的機(jī)制,這里是因為這張表一共就2個字段,而這inx_name索引樹就已經(jīng)包含了id和name,這時候選擇用主鍵和二級索引,它會優(yōu)先選擇二級索引因為它的索引樹大小會小很多。
如果有很多其他字段,可能會選擇主鍵索引,因為你選擇了二級索引還得做回表操作

  • ALL:即全表掃描,掃描你的聚簇索引的所有葉子節(jié)點。通常情況下這需要增加索引來進(jìn)行優(yōu)化了
 explain select * from actor;

possible_keys列

這一列顯示查詢可能使用哪些索引來查找。
explain時可能出現(xiàn)possible_keys有列,而key顯示NULL的情況,這種情況是因為表中數(shù)據(jù)不多,mysql認(rèn)為索引對此查詢幫助不大,所以選擇全表掃描。
如果該列是NULL,則沒有相關(guān)的索引。在這種情況下可以通過檢查where子句看是否可以創(chuàng)建一個適當(dāng)?shù)乃饕齺硖岣卟樵冃阅?,然后用explain查看效果。

key列

這一列顯示MySQL使用采用那個索引來優(yōu)化對該表的訪問。
如果沒有使用索引,則該列是NULL。如果想強(qiáng)制MySQL使用或忽視possibe_keys列中的索引,在查詢中使用force index、ignore index。

key_len列

這一列顯示了MySQL在索引里使用的字節(jié)數(shù),通過這個值可以算出具體使用了索引中的哪些列。
舉例來說,film_actor的聯(lián)合索引 idx_film_actor_id 由 film_id 和 actor_id 兩個int列組成,并且每個int是4字節(jié)。通過結(jié)果中的key_len=4可推斷出查詢使用了第一個列:film_id列來執(zhí)行索引查找。

explain select * from film_actor where film_id = 2;

ref列

這一列顯示了在key列記錄的索引中,表查找值所用到的列或常量,常見的有:const(常量),字段名(例:film.id)

rows列

這一列是MySQL估計要讀取并檢測的行數(shù),注意這個不是結(jié)果集里的行數(shù)

Extra列

這一列展示的是額外信息,常見的重要值如下:

  • 1.Using index:使用覆蓋索引 (不會回表)

覆蓋索引定義:MySQL執(zhí)行計劃explain結(jié)果里的key有使用索引,如果select后面查詢的字段都可以從這個索引的樹中獲取,這種情況一般可以說用到了覆蓋索引,extra里一般都有using index;覆蓋索引一般針對的是輔助索引,整個查詢結(jié)構(gòu)只通過輔助索引就能拿到結(jié)構(gòu),不需要通過輔助所以樹找到主鍵,再通過主鍵去主鍵索引樹里獲取其他字段值

explain select film_id from film_actor where film_id = 1;

  • 2.Using where:使用where語句來處理結(jié)果,并且查詢的列未被索引覆蓋
explain select * from actor where name = 'a';

  • 3.Using index condition:查詢的列不完全被索引覆蓋,where條件中是一個前導(dǎo)列的范圍
explain select * from film_actor where film_id > 1;

1.Using temporary:MySQL需要創(chuàng)建一張臨時表來處理查詢。出現(xiàn)這種情況一般是要進(jìn)行優(yōu)化的,首先是想導(dǎo)用索引來優(yōu)化。

4.1 actor.name沒有索引,此時創(chuàng)建一張臨時表來distinct

explain select distinct name from actor;

4.2 film.name創(chuàng)建了idx_name索引,此時查詢時extra時using index ,沒有用臨時表

explain select distinct name from film;

5.Using filesort:將用外部排序而不是索引排序,數(shù)據(jù)較小時從內(nèi)存排序,否則需要再磁盤完成排序。這種情況下一般也是要考慮使用索引來優(yōu)化的

5.1 actor.name未創(chuàng)建索引,會瀏覽actor整個表,保存排序關(guān)鍵字name和對應(yīng)的id,然后排序name并檢索行記錄

explain select * from actor order by name;

5.2 film.name建立了idx_name索引,此時查詢時extra是using index

explain select * from film order by name;

6.Select tables optimized away:使用某些聚合函數(shù)(比如 max、min)來訪問存在索引的某個字段

explain select min(id) from film;

到此這篇關(guān)于MySQL之Explain詳解的文章就介紹到這了,更多相關(guān)MySQL Explain詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL異常宕機(jī)無法啟動的處理過程

    MySQL異常宕機(jī)無法啟動的處理過程

    MySQL宕機(jī)是指MySQL數(shù)據(jù)庫服務(wù)突然停止運(yùn)行,通常可能是由于硬件故障、軟件錯誤、資源耗盡、網(wǎng)絡(luò)中斷、配置問題或是惡意攻擊等導(dǎo)致,當(dāng)MySQL發(fā)生宕機(jī)時,系統(tǒng)可能無法提供數(shù)據(jù)訪問,本文給大家介紹了MySQL異常宕機(jī)無法啟動的處理過程,需要的朋友可以參考下
    2024-08-08
  • 解決mysql時區(qū)問題導(dǎo)致錯誤Incorrect datetime value: '1970-01-01 00:00:01'

    解決mysql時區(qū)問題導(dǎo)致錯誤Incorrect datetime value: &apo

    這篇文章主要介紹了解決mysql時區(qū)問題導(dǎo)致錯誤Incorrect datetime value: '1970-01-01 00:00:01',具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 超越MySQL 對流行數(shù)據(jù)庫進(jìn)行分支的知識小結(jié)

    超越MySQL 對流行數(shù)據(jù)庫進(jìn)行分支的知識小結(jié)

    盡管MySQL是最受歡迎的程序之一,但是許多開發(fā)人員認(rèn)為有必要將其拆分成其他項目,并且每個分支項目都有自己的專長。該需求,以及 Oracle 對核心產(chǎn)品增長緩慢的擔(dān)憂,導(dǎo)致出現(xiàn)了許多開發(fā)人員感興趣的子項目和分支
    2012-01-01
  • 關(guān)于MySQL數(shù)據(jù)庫死鎖的案例和解決方案

    關(guān)于MySQL數(shù)據(jù)庫死鎖的案例和解決方案

    MySQL Update語句防止死鎖是指在修改MySQL數(shù)據(jù)庫的數(shù)據(jù)時,為避免多個進(jìn)程同時修改同一數(shù)據(jù)行而造成死鎖的情況,引入了一些機(jī)制來防止死鎖的產(chǎn)生,本文介紹了一個 MySQL 數(shù)據(jù)庫死鎖的案例和解決方案,需要的朋友可以參考下
    2023-09-09
  • SQL?INSERT及批量的幾種方式總結(jié)

    SQL?INSERT及批量的幾種方式總結(jié)

    SQL提供了INSERT語句,用于將一行或多行插入表中,下面這篇文章主要給大家介紹了關(guān)于SQL?INSERT及批量的幾種方式,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • mysql 顯示SQL語句執(zhí)行時間的代碼

    mysql 顯示SQL語句執(zhí)行時間的代碼

    查看 MySQL 語法 詳細(xì)執(zhí)行時間 與 CPU/記憶體使用量: MySQL Query Profiler
    2009-08-08
  • ARM64架構(gòu)下安裝mysql5.7.22的全過程

    ARM64架構(gòu)下安裝mysql5.7.22的全過程

    這篇文章主要介紹了ARM64架構(gòu)下安裝mysql5.7.22的全過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • Mysql 聚合函數(shù)嵌套使用操作

    Mysql 聚合函數(shù)嵌套使用操作

    這篇文章主要介紹了Mysql 聚合函數(shù)嵌套使用操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Node-Red實現(xiàn)MySQL數(shù)據(jù)庫連接的方法

    Node-Red實現(xiàn)MySQL數(shù)據(jù)庫連接的方法

    這篇文章主要介紹了Node-Red實現(xiàn)MySQL數(shù)據(jù)庫連接的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • Mysql數(shù)據(jù)庫表中為什么有索引卻沒有提高查詢速度

    Mysql數(shù)據(jù)庫表中為什么有索引卻沒有提高查詢速度

    你有沒有想起過為什么明明再數(shù)據(jù)庫中有索引,但是查詢速度卻并沒有希望的那樣快?本篇文章將帶給你答案,跟小編一起看看吧
    2022-02-02

最新評論