MySQL關(guān)鍵字explain的用法詳解
使用EXPLAIN關(guān)鍵字,可以獲取關(guān)于查詢執(zhí)行計劃的詳細信息,包括表的訪問順序、連接方式、索引使用情況等,這些信息能夠幫助你確定查詢是否有效利用了索引,以及是否存在潛在的性能瓶頸。
要使用EXPLAIN關(guān)鍵字,只需在查詢語句前加上"EXPLAIN"關(guān)鍵字即可,例如:
EXPLAIN SELECT * FROM table_name WHERE column_name = 'value';
執(zhí)行以上語句后,MySQL會返回一個結(jié)果集,包含了查詢執(zhí)行計劃的詳細信息。該結(jié)果集中的每一行對應(yīng)查詢執(zhí)行計劃中的一步操作,你可以通過分析這些數(shù)據(jù)來確定查詢的性能瓶頸以及優(yōu)化的方向。
這些信息包括以下列:
id: 查詢執(zhí)行計劃中每個操作的唯一標(biāo)識,
select_type: 操作類型,如簡單查詢、聯(lián)合查詢等,
table: 操作涉及的表名,
type: 表訪問的方式,如全表掃描、索引掃描等,
possible_keys: 可能使用的索引,
key: 實際使用的索引,
key_len: 實際使用的索引長度,
ref: 與索引比較的列或常量值,
rows: 預(yù)估的結(jié)果集行數(shù),
Extra: 額外的信息,如排序、臨時表等。
通過分析這些信息,你可以更好地理解查詢的執(zhí)行過程,并且采取相應(yīng)的優(yōu)化措施,例如創(chuàng)建合適的索引、優(yōu)化查詢語句等,以提高MySQL查詢的性能。
0 環(huán)境準(zhǔn)備
CREATE TABLE `t_role` ( `id` varchar(32) NOT NULL, `role_name` varchar(255) DEFAULT NULL, `role_code` varchar(255) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_role_name` (`role_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `t_user` ( `id` varchar(32) NOT NULL, `username` varchar(45) NOT NULL, `password` varchar(96) NOT NULL, `name` varchar(45) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_user_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `user_role` ( `id` int(11) NOT NULL auto_increment , `user_id` varchar(32) DEFAULT NULL, `role_id` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_ur_user_id` (`user_id`), KEY `fk_ur_role_id` (`role_id`), CONSTRAINT `fk_ur_role_id` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_ur_user_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `t_user` (`id`, `username`, `password`, `name`) values('1','super','$2a$10$TJ4TmCdK.X4wv/tCqHW14.w70U3CC33CeVncD3SLmyMXMknstqKRe',' 超級管理員'); insert into `t_user` (`id`, `username`, `password`, `name`) values('2','admin','$2a$10$TJ4TmCdK.X4wv/tCqHW14.w70U3CC33CeVncD3SLmyMXMknstqKRe',' 系統(tǒng)管理員'); insert into `t_user` (`id`, `username`, `password`, `name`) values('3','itcast','$2a$10$8qmaHgUFUAmPR5pOuWhYWOr291WJYjHelUlYn07k5ELF8ZCrW0Cui', 'test02'); insert into `t_user` (`id`, `username`, `password`, `name`) values('4','stu1','$2a$10$pLtt2KDAFpwTWLjNsmTEi.oU1yOZyIn9XkziK/y/spH5rftCpUMZa','學(xué) 生1'); insert into `t_user` (`id`, `username`, `password`, `name`) values('5','stu2','$2a$10$nxPKkYSez7uz2YQYUnwhR.z57km3yqKn3Hr/p1FR6ZKgc18u.Tvqm','學(xué) 生2'); insert into `t_user` (`id`, `username`, `password`, `name`) values('6','t1','$2a$10$TJ4TmCdK.X4wv/tCqHW14.w70U3CC33CeVncD3SLmyMXMknstqKRe','老師 1'); INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('5','學(xué) 生','student','學(xué)生'); INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('7','老 師','teacher','老師'); INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('8','教 學(xué)管理員','teachmanager','教學(xué)管理員'); INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('9','管 理員','admin','管理員'); INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('10','超 級管理員','super','超級管理員'); INSERT INTO user_role(id,user_id,role_id) VALUES(NULL, '1', '5'),(NULL, '1', '7'), (NULL, '2', '8'),(NULL, '3', '9'),(NULL, '4', '8'),(NULL, '5', '10') ;
1 explain 之 id
id 字段是 select查詢的序列號,是一組數(shù)字,表示的是查詢中執(zhí)行select子句或者是操作表的順序。id 情況有三種:
1) id 相同表示加載表的順序是從上到下。
explain select * from t_role r, t_user u, user_role ur where r.id = ur.role_id and u.id = ur.user_id ;
2) id 不同id值越大,優(yōu)先級越高,越先被執(zhí)行。
EXPLAIN SELECT * FROM t_role WHERE id = (SELECT role_id FROM user_role WHERE user_id = (SELECT id FROM t_user WHERE username = 'stu1'))
3) id 有相同,也有不同,同時存在。id相同的可以認(rèn)為是一組,從上往下順序執(zhí)行;在所有的組中,id的值越大,優(yōu)先級越高,越先執(zhí)行。
2 explain 之 select_type
表示 SELECT 的類型,常見的取值,如下表所示:
select_type | 含義 |
---|---|
SIMPLE | 簡單的select查詢,查詢中不包含子查詢或者UNION |
PRIMARY | 查詢中若包含任何復(fù)雜的子查詢,最外層查詢標(biāo)記為該標(biāo)識 |
SUBQUERY | 在SELECT 或 WHERE 列表中包含了子查詢 |
DERIVED | 在FROM 列表中包含的子查詢,被標(biāo)記為 DERIVED(衍生) MYSQL會遞歸執(zhí)行這些子查詢,把結(jié)果放在臨時表中 |
UNION | 若第二個SELECT出現(xiàn)在UNION之后,則標(biāo)記為UNION ; 若UNION包含在FROM子句的子查詢中,外層SELECT將被標(biāo)記為 : DERIVED |
UNION RESULT | 從UNION表獲取結(jié)果的SELECT |
3 explain 之 table
展示這一行的數(shù)據(jù)是關(guān)于哪一張表的
4 explain 之 type
type 顯示的是訪問類型,是較為重要的一個指標(biāo),可取值為:
select_type | 含義 |
---|---|
NULL | MySQL不訪問任何表,索引,直接返回結(jié)果 |
system | 表只有一行記錄(等于系統(tǒng)表),這是const類型的特例,一般不會出現(xiàn) |
const | 表示通過索引一次就找到了,const 用于比較primary key 或者 unique 索引。因為只匹配一行數(shù)據(jù),所以很快。如將主鍵置于where列表中,MySQL 就能將該查詢轉(zhuǎn)換為一個常亮。const于將"主鍵" 或 “唯一” 索引的所有部分與常量值進行比較 |
eq_ref | 類似ref,區(qū)別在于使用的是唯一索引,使用主鍵的關(guān)聯(lián)查詢,關(guān)聯(lián)查詢出的記錄只有一條。常見于主鍵或唯一索引掃描 |
ref | 非唯一性索引掃描,返回匹配某個單獨值的所有行。本質(zhì)上也是一種索引訪問,返回所有匹配某個單獨值的所有行(多個) |
range | 只檢索給定返回的行,使用一個索引來選擇行。 where 之后出現(xiàn) between , < , > , in 等操作。 |
index | index 與 ALL的區(qū)別為 index 類型只是遍歷了索引樹, 通常比ALL 快, ALL 是遍歷數(shù)據(jù)文件。 |
all | 將遍歷全表以找到匹配的行 |
結(jié)果值從最好到最壞以此是:null > system > const > eq_ref > ref > range > index > ALL
一般來說, 我們需要保證查詢至少達到 range 級別, 最好達到ref 。
5 explain 之 key
possible_keys : 顯示可能應(yīng)用在這張表的索引, 一個或多個。
key : 實際使用的索引, 如果為NULL, 則沒有使用索引。
key_len : 表示索引中使用的字節(jié)數(shù), 該值為索引字段最大可能長度,并非實際使用長度,在不損失精確性的前提下, 長度越短越好 。
6 explain 之 rows
掃描行的數(shù)量。
7 explain 之 extra
其他的額外的執(zhí)行計劃信息,在該列展示 。
到此這篇關(guān)于MySQL關(guān)鍵字explain用法詳解的文章就介紹到這了,更多相關(guān)MySQL關(guān)鍵字explain內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決當(dāng)MySQL數(shù)據(jù)庫遇到Syn Flooding問題
Syn攻擊常見于應(yīng)用服務(wù)器,而數(shù)據(jù)庫服務(wù)器在內(nèi)網(wǎng)中,應(yīng)該很難碰到類似的攻擊,這篇文章主要介紹了當(dāng)MySQL數(shù)據(jù)庫遇到Syn Flooding問題 ,需要的朋友可以參考下2019-06-06mysql中text,longtext,mediumtext區(qū)別小結(jié)
在 MySQL 中,text、mediumtext 和 longtext 都是用來存儲大量文本數(shù)據(jù)的數(shù)據(jù)類型,本文就來詳細的介紹一下這三種類型的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2023-12-12mysql8.0.20安裝與連接navicat的方法及注意事項
這篇文章主要介紹了mysql8.0.20安裝與連接navicat的方法及注意事項,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05mysql數(shù)據(jù)庫基礎(chǔ)知識點與操作小結(jié)
這篇文章主要介紹了mysql數(shù)據(jù)庫基礎(chǔ)知識點與操作,總結(jié)分析了mysql數(shù)據(jù)庫修改數(shù)據(jù)表、增刪改查及數(shù)據(jù)庫函數(shù)基本功能,需要的朋友可以參考下2020-01-01MySQL錯誤ERROR 2002 (HY000): Can''t connect to local MySQL ser
這篇文章主要介紹了MySQL錯誤ERROR 2002 (HY000): Can't connect to local MySQL server through socket,需要的朋友可以參考下2014-10-10Mysql創(chuàng)建視圖中文亂碼如何修改docker里的配置
這篇文章主要介紹了Mysql創(chuàng)建視圖中文亂碼如何修改docker里的配置,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-10-10MySql Group By對多個字段進行分組的實現(xiàn)方法
這篇文章主要介紹了MySql Group By對多個字段進行分組的實現(xiàn)方法,需要的朋友可以參考下2017-09-09