日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

mysql解释器优化_MySQL——SQL性能分析优化利器之Explain

發(fā)布時(shí)間:2025/4/16 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql解释器优化_MySQL——SQL性能分析优化利器之Explain 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

系統(tǒng)性能的優(yōu)劣取決于我們sql的查詢(xún)速度,MySQL Explain命令是分析SQL性能及優(yōu)化不可缺少的一部分。

Explain被我們稱(chēng)為解釋器,通過(guò) explain 我們可以知道以下信息:表的讀取順序,數(shù)據(jù)讀取操作的類(lèi)型,可能會(huì)使用哪些索引,實(shí)際真正使用了哪些索引,表之間的引用,每張表有多少行被優(yōu)化器查詢(xún)等信息。

Explain基本語(yǔ)法

explain [extended|partition]select

在select前加explain關(guān)鍵字,MySQL會(huì)返回該查詢(xún)的執(zhí)行計(jì)劃而不是執(zhí)行這條SQL

根據(jù)語(yǔ)法我們知道explain還有兩種其他的用法:

explain extended :能夠在原本explain的基礎(chǔ)上額外的提供一些查詢(xún)優(yōu)化的信息,這些信息可以通過(guò)mysql的show warnings命令得到,從而看出優(yōu)化器優(yōu)化了什么。

explain partitions:相比 explain 多了個(gè) partitions 字段,如果查詢(xún)是基于分區(qū)表的話(huà),會(huì)顯示查詢(xún)將訪(fǎng)問(wèn)的分區(qū)。

Explain列的含義

id:id列的編號(hào)是 select 的序列號(hào),有幾個(gè) select 就有幾個(gè)id,id不同,id值越大,優(yōu)先級(jí)越高,越先 執(zhí)行

select_type :顯示本行是簡(jiǎn)單或復(fù)雜select。如果查詢(xún)有任何復(fù)雜的子查詢(xún),則最外層標(biāo)記為 PRIMARY(DERIVED、UNION、UNION RESUlT)

table :訪(fǎng)問(wèn)查詢(xún)的表名或表別名|

type :表的訪(fǎng)問(wèn)類(lèi)型( MySQL 如何查詢(xún)表中的行記錄)效率高低:const eq_ref/ref/range/index/all

possible_keys:指出MySQL能使用哪個(gè)索引在該表中找到行

key :MySQL實(shí)際決定使用的鍵(索引)。如果沒(méi)有選擇索引,鍵是NULL

key_len :實(shí)際使用的索引長(zhǎng)度(單位:字節(jié))該字段顯示為索引字段的最大可能長(zhǎng)度,并非實(shí)際使 用長(zhǎng)度。

ref :用于索引查找的值的來(lái)源,如果值未常量,則 ref 為 const

rows :預(yù)計(jì)查詢(xún)需要掃描的行數(shù)(在表或索引樹(shù)中)

filtered :查詢(xún)條件所過(guò)濾的行記錄數(shù)占比

Extra:額外的信息:

Using filesort:說(shuō)明mysql會(huì)對(duì)數(shù)據(jù)適用一個(gè)外部的索引排序。而不是按照表內(nèi)的索引順序進(jìn)行讀取。MySQL中無(wú)法利用索引完成排序操作稱(chēng)為“文件排序”

Using temporary:使用了臨時(shí)表保存中間結(jié)果,mysql在查詢(xún)結(jié)果排序時(shí)使用臨時(shí)表。常見(jiàn)于排序order by和分組查詢(xún)group by。

Using index:表示相應(yīng)的select操作用使用覆蓋索引,避免訪(fǎng)問(wèn)了表的數(shù)據(jù)行。如果同時(shí)出現(xiàn)using where,表名索引被用來(lái)執(zhí)行索引鍵值的查找;如果沒(méi)有同時(shí)出現(xiàn)using where,表名索引用來(lái)讀取數(shù)據(jù)而非執(zhí)行查詢(xún)動(dòng)作。

Using where :表明使用where過(guò)濾

using join buffer:使用了連接緩存

impossible where:where子句的值總是false,不能用來(lái)獲取任何元組

select tables optimized away:在沒(méi)有g(shù)roup by子句的情況下,基于索引優(yōu)化Min、max操作或者對(duì)于MyISAM存儲(chǔ)引擎優(yōu)化count(*),不必等到執(zhí)行階段再進(jìn)行計(jì)算,查詢(xún)執(zhí)行計(jì)劃生成的階段即完成優(yōu)化。

distinct:優(yōu)化distinct操作,在找到第一匹配的元組后即停止找同樣值的動(dòng)作

詳細(xì)介紹列的含義

1. id列

id 的值為數(shù)值,其表示的是SQL執(zhí)行中的執(zhí)行順序,規(guī)則如下:

如果 id 值相同,則執(zhí)行順序?yàn)?#xff1a;從上到下

如果 id 值不同,則執(zhí)行順序?yàn)?#xff1a; id 值越大的越先執(zhí)行

如果 id 值相同,則可以認(rèn)為他們是同一分組,同一分組中執(zhí)行順序?yàn)?#xff1a;從上到下

在所有組中, id 值越大的越先執(zhí)行

如果 id 值為 null ,則表示這是一個(gè)臨時(shí)表,臨時(shí)表不在SQL總出現(xiàn),因此它的id是NULL

MySQL將 select 查詢(xún)分為簡(jiǎn)單查詢(xún)和復(fù)雜查詢(xún)。復(fù)雜查詢(xún)分為三類(lèi):簡(jiǎn)單子查詢(xún)、派生表(from語(yǔ)句中的子查詢(xún))、union 查詢(xún)。

2. select_type列

這一列表示的是對(duì)應(yīng)行對(duì)應(yīng)的查詢(xún)類(lèi)型,到底是簡(jiǎn)單查詢(xún)還是復(fù)雜查詢(xún),如果是復(fù)雜的查詢(xún),又是簡(jiǎn)單子查詢(xún)、from語(yǔ)句中的子查詢(xún)、union 查詢(xún)復(fù)雜查詢(xún)中的哪一種。

simple :簡(jiǎn)單的select查詢(xún),查詢(xún)中不包含子查詢(xún)或者 union

primary:復(fù)雜查詢(xún)最外層的查詢(xún)類(lèi)型

subquery :在 select 或 where 列表中包含了子查詢(xún)

derived:包含在 from 子句中的子查詢(xún)。MySQL會(huì)將結(jié)果存放在一個(gè)臨時(shí)表中,也稱(chēng)為派生表

union:union查詢(xún)語(yǔ)句出現(xiàn)在union之后的第二個(gè)和以后的查詢(xún)會(huì)被標(biāo)為union類(lèi)型

union result:從 union 構(gòu)建的臨時(shí)表檢索結(jié)果的查詢(xún)類(lèi)型

table列

這一列看名稱(chēng)就知道是指的具體查詢(xún)的table名稱(chēng)。

當(dāng) from 子句中有子查詢(xún)時(shí),table列是 格式,表示當(dāng)前查詢(xún)依賴(lài) id=N 的查詢(xún),于是先執(zhí)行 id=N 的查詢(xún)。當(dāng)有 union 時(shí),UNION RESULT 的 table 列的值為 ,1和2表示參與 union 的 select 行id。

4. type列

這一列表示關(guān)聯(lián)類(lèi)型或訪(fǎng)問(wèn)類(lèi)型,即MySQL決定如何查找表中的行

最優(yōu)到最差分別為:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

const, system:Mysql查詢(xún)對(duì)其進(jìn)行優(yōu)化并轉(zhuǎn)化為一個(gè)常量,只查詢(xún)一次就搜索出結(jié)果,用于 primary key 或 unique key 的所有列與常數(shù)比較時(shí),所以表最多有一個(gè)匹配行,讀取1次,速度比較快。

eq_ref:唯一性索引掃描,對(duì)于每個(gè)索引鍵,表中只有一條記錄與之匹配。常見(jiàn)于主鍵或唯一索引掃描

ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者聯(lián)合索引的部分前綴,索引要和某個(gè)值相比較,可能會(huì)找到多個(gè)符合條件的行.

ref_or_null:與ref類(lèi)型差不多,但是這種類(lèi)型可以搜索為Null的行

index_merge:使用了索引合并的優(yōu)化方法

6.range: 范圍掃描通常出現(xiàn)在 in(), between ,> ,= 等操作中。使用一個(gè)索引來(lái)檢索給定范圍的行

7 index:Full Index Scan,Index與All區(qū)別為index類(lèi)型只遍歷索引樹(shù)。這通常比ALL快,因?yàn)樗饕募ǔ1葦?shù)據(jù)文件小

All:掃描全表,與index其實(shí)都是掃描全表進(jìn)行檢索數(shù)據(jù),區(qū)別在于,index類(lèi)型是掃描索引樹(shù)進(jìn)行數(shù)據(jù)掃描,而All類(lèi)型則是直接掃磁盤(pán),所以相對(duì)index類(lèi)型比較慢

5. possible_keys列

顯示此次查詢(xún)可能會(huì)用到的索引,一個(gè)或者是多個(gè),查詢(xún)涉及到的字段上若存在索引,則該索引將被列出,但不一定會(huì)應(yīng)用。

explain 時(shí)可能出現(xiàn) possible_keys 有列,而 key 顯示 NULL 的情況,這種情況是因?yàn)楸碇袛?shù)據(jù)不多,mysql認(rèn)為索引對(duì)此查詢(xún)幫助不大,選擇了全表查詢(xún)。

如果該列是NULL,則沒(méi)有相關(guān)的索引。在這種情況下,可以通過(guò)檢查 where 子句看是否可以創(chuàng)造一個(gè)適當(dāng)?shù)乃饕齺?lái)提高查詢(xún)性能,然后用 explain 查看效果。但是有一種情況也可能會(huì)走索引,如果出現(xiàn) 覆蓋索引 的情況即使該列為null 依然有可能會(huì)走索引查詢(xún)

6. key列

mysql實(shí)際采用哪個(gè)索引來(lái)優(yōu)化對(duì)該表的訪(fǎng)問(wèn),如果想強(qiáng)制指定索引或者忽視索引,可在查詢(xún)中使用 force index、ignore index。

7. key_len列

表示索引中使用的字節(jié)數(shù),可通過(guò)該列計(jì)算查詢(xún)中使用的索引的長(zhǎng)度,在不損失精確性的情況下,長(zhǎng)度越短越好,key_len表示的是索引的最大長(zhǎng)度,而不是實(shí)際使用長(zhǎng)度。

key_len計(jì)算規(guī)則如下:

字符型

char(n):n字節(jié)長(zhǎng)度

varchar(n):2字節(jié)存儲(chǔ)字符串長(zhǎng)度,如果是utf-8,則長(zhǎng)度 3n + 2

數(shù)值型

tinyint:1字節(jié)

smallint:2字節(jié)

int:4字節(jié)

bigint:8字節(jié)

時(shí)間類(lèi)型

date:3字節(jié)

timestamp:4字節(jié)

datetime:8字節(jié)

如果字段允許為 NULL,需要額外增加1字節(jié)記錄是否為 NULL

8. ref列

這一列顯示了在key列記錄的索引中,表查找值所用到的列或常量,常見(jiàn)的有:const(常量),func,NULL,字段名

9. rows列

這一列表示這條SQL可能要檢索的數(shù)據(jù)行數(shù),并不是返回結(jié)果集的行數(shù)。

10.Extra列

這一列展示的是一些額外的信息,但是也是十分重要的,對(duì)于我們提升SQL 的檢索性能是很有幫助的。

常見(jiàn)的類(lèi)型如下:

distinct: 一旦mysql找到了與行相聯(lián)合匹配的行,就不再搜索了

Using index:表示相應(yīng)的select操作中使用了覆蓋索引(Covering Index),避免訪(fǎng)問(wèn)了表的數(shù)據(jù)行,效率還是非常可觀(guān)的。

覆蓋索引:簡(jiǎn)單的理解就是這次select的字段只從索引中就可以獲取的到,沒(méi)有必要再去浪費(fèi)一次IO讀取行數(shù)據(jù),換句話(huà)說(shuō)就是查詢(xún)的列被索引列所覆蓋

Using where:就是使用了where條件查詢(xún)。mysql服務(wù)器將在存儲(chǔ)引擎檢索行后再進(jìn)行過(guò)濾。就是先讀取整行數(shù)據(jù),再按 where 條件進(jìn)行檢查,符合就留下,不符合就丟棄。

Using temporary:mysql需要?jiǎng)?chuàng)建一張臨時(shí)表來(lái)處理查詢(xún)結(jié)果。出現(xiàn)這種情況一般是要進(jìn)行優(yōu)化的,首先是想到用索引來(lái)優(yōu)化。這種類(lèi)型常見(jiàn)于order by 和group by的查詢(xún)中

Using filesort:對(duì)查詢(xún)結(jié)果進(jìn)行外部索引排序而不是按索引次序從表里讀取行,這種情況可以考慮建立索引來(lái)進(jìn)行優(yōu)化。

總結(jié)

以上是生活随笔為你收集整理的mysql解释器优化_MySQL——SQL性能分析优化利器之Explain的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。