mysql中explain的具體實(shí)現(xiàn)
一、MySQL EXPLAIN 是什么?
EXPLAIN 是 MySQL 中用于分析 SQL 執(zhí)行計(jì)劃的核心命令,它能告訴你 MySQL 優(yōu)化器會(huì)如何執(zhí)行這條 SQL(比如用什么索引、掃描多少行、連接方式等),是優(yōu)化慢 SQL 的必備工具。
可以把它理解為:你寫(xiě)了一條 SQL 想讓 MySQL 執(zhí)行,EXPLAIN 會(huì)提前告訴你 MySQL 的“執(zhí)行思路”—— 走哪條路、做哪些操作、效率怎么樣,幫你找到 SQL 里的性能瓶頸。
二、基本用法
1. 語(yǔ)法
EXPLAIN + 你的SQL語(yǔ)句; -- 示例 EXPLAIN SELECT * FROM user WHERE id = 1;
如果想查看更詳細(xì)的執(zhí)行計(jì)劃(比如執(zhí)行時(shí)的成本、臨時(shí)表等),可以用:
EXPLAIN ANALYZE SELECT * FROM user WHERE id = 1; -- MySQL 8.0 及以上支持
2. 輸出字段說(shuō)明
執(zhí)行 EXPLAIN 后會(huì)返回一個(gè)結(jié)果集,核心字段如下(新手先掌握這 8 個(gè)核心字段即可):
| 字段 | 核心含義 |
|---|---|
| id | SQL 執(zhí)行的順序(子查詢(xún)/聯(lián)表時(shí)會(huì)有多個(gè) id,數(shù)字越大越先執(zhí)行) |
| select_type | 查詢(xún)類(lèi)型(比如簡(jiǎn)單查詢(xún)、子查詢(xún)、聯(lián)表查詢(xún)、衍生表等) |
| table | 本次執(zhí)行涉及的表名 |
| type | 訪(fǎng)問(wèn)類(lèi)型(核心!判斷性能的關(guān)鍵,從差到好:ALL < index < range < ref < eq_ref < const/system) |
| possible_keys | MySQL 可能會(huì)選擇的索引(候選索引) |
| key | MySQL 實(shí)際使用的索引(如果為 NULL,說(shuō)明沒(méi)用到索引) |
| rows | MySQL 預(yù)估要掃描的行數(shù)(數(shù)值越小越好) |
| Extra | 額外信息(比如 Using index 走覆蓋索引、Using where 過(guò)濾條件、Using filesort 排序等) |
三、核心字段詳解(新手重點(diǎn))
1. type(訪(fǎng)問(wèn)類(lèi)型)
這是 EXPLAIN 中最重要的字段,直接反映 SQL 的性能層級(jí),常見(jiàn)值從差到優(yōu)排序:
- ALL:全表掃描(最差!會(huì)遍歷整個(gè)表),比如 SELECT * FROM user; 且無(wú)任何條件。
- index:全索引掃描(比 ALL 好一點(diǎn),但仍?huà)呙枵麄€(gè)索引),比如查詢(xún)的字段都在索引里,但無(wú)過(guò)濾條件。
- range:索引范圍掃描(比如用 >、<、BETWEEN、IN 等),比如 SELECT * FROM user WHERE id BETWEEN 1 AND 10;。
- ref:非唯一索引掃描(匹配多行),比如 SELECT * FROM user WHERE name = '張三';(name 是普通索引)。
- eq_ref:唯一索引掃描(匹配一行),比如聯(lián)表查詢(xún)時(shí)用主鍵/唯一索引關(guān)聯(lián),SELECT * FROM user u JOIN order o ON u.id = o.user_id;。
- const/system:查詢(xún)結(jié)果能確定為一行(最優(yōu)),比如用主鍵查詢(xún) SELECT * FROM user WHERE id = 1;。
2. key(實(shí)際使用的索引)
- 如果 key 為 NULL,說(shuō)明 MySQL 沒(méi)用到索引,大概率是 SQL 寫(xiě)得有問(wèn)題(比如用了函數(shù)操作索引字段、條件不匹配索引等)。
- 示例:如果 user 表的 id 是主鍵(默認(rèn)索引),執(zhí)行 EXPLAIN SELECT * FROM user WHERE id = 1;,key 列會(huì)顯示 PRIMARY(主鍵索引名)。
3. Extra(關(guān)鍵提示)
- Using index:走了“覆蓋索引”(查詢(xún)的字段都在索引里,無(wú)需回表查數(shù)據(jù)),性能極佳。
示例:user 表有索引 idx_name_age (name, age),執(zhí)行 EXPLAIN SELECT name, age FROM user WHERE name = '張三';,Extra 會(huì)顯示 Using index。
- Using where:MySQL 會(huì)先掃描數(shù)據(jù),再用 WHERE 條件過(guò)濾(如果同時(shí)有 Using index,說(shuō)明先走索引再過(guò)濾)。
- Using filesort:MySQL 需額外做排序(不是用索引排序),性能差,比如 SELECT * FROM user ORDER BY name; 但 name 無(wú)索引。
- Using temporary:MySQL 需創(chuàng)建臨時(shí)表(比如 GROUP BY 沒(méi)用到索引),性能差,要優(yōu)化。
四、實(shí)戰(zhàn)示例
假設(shè)有一張 user 表,結(jié)構(gòu)如下:
CREATE TABLE `user` ( `id` int PRIMARY KEY AUTO_INCREMENT, `name` varchar(20) NOT NULL, `age` int, `gender` tinyint, INDEX `idx_name` (`name`) -- 普通索引 );
示例 1:全表掃描(差)
EXPLAIN SELECT * FROM user WHERE age = 20;
- type:ALL(全表掃描)
- key:NULL(沒(méi)用到索引)
- Extra:Using where(掃描后過(guò)濾)
- 優(yōu)化:給 age 加索引 ALTER TABLE user ADD INDEX idx_age (age);。
示例 2:使用索引(好)
EXPLAIN SELECT * FROM user WHERE name = '張三';
- type:ref(非唯一索引掃描)
- key:idx_name(用到了 name 的索引)
- rows:預(yù)估掃描行數(shù)(比如 10 行,遠(yuǎn)小于全表行數(shù))。
示例 3:覆蓋索引(優(yōu))
EXPLAIN SELECT name FROM user WHERE name = '張三';
- type:ref
- key:idx_name
- Extra:Using index(覆蓋索引,無(wú)需回表)。
五、使用注意事項(xiàng)
- EXPLAIN 的 rows 是 MySQL 預(yù)估的掃描行數(shù),不是實(shí)際行數(shù),但能反映性能趨勢(shì)(數(shù)值越小越好)。
- EXPLAIN 只分析執(zhí)行計(jì)劃,不會(huì)實(shí)際執(zhí)行 SQL(除非用 EXPLAIN ANALYZE),所以可以放心在生產(chǎn)環(huán)境使用。
- 即使 possible_keys 有值,key 也可能為 NULL —— 說(shuō)明 MySQL 認(rèn)為走索引不如全表掃描快(比如表數(shù)據(jù)量極小)。
總結(jié)
- EXPLAIN 是分析 SQL 執(zhí)行計(jì)劃的核心工具,重點(diǎn)看 type(訪(fǎng)問(wèn)類(lèi)型)、key(實(shí)際索引)、Extra(額外提示)三個(gè)字段。
- 優(yōu)化目標(biāo):盡量讓 type 達(dá)到 range 及以上,key 不為 NULL,避免 Extra 出現(xiàn) Using filesort/Using temporary。
- 最理想的執(zhí)行計(jì)劃:type 為 const/system + key 有值 + Extra 顯示 Using index。
到此這篇關(guān)于mysql中explain的具體實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)mysql explain內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mysql中explain用法詳解
- Mysql中explain作用詳解
- mysql總結(jié)之explain
- MySQL性能分析及explain的使用說(shuō)明
- MySQL中通過(guò)EXPLAIN如何分析SQL的執(zhí)行計(jì)劃詳解
- 詳解MySQL中EXPLAIN解釋命令及用法講解
- MySQL中執(zhí)行計(jì)劃explain命令示例詳解
- MySQL使用explain命令查看與分析索引的使用情況
- MySql中如何使用 explain 查詢(xún) SQL 的執(zhí)行計(jì)劃
- 全面解析MySQL?Explain如何優(yōu)化SQL查詢(xún)性能
- MYSQL explain 執(zhí)行計(jì)劃
相關(guān)文章
php中關(guān)于mysqli和mysql區(qū)別的一些知識(shí)點(diǎn)分析
看書(shū)、看視頻的時(shí)候一直沒(méi)有搞懂mysqli和mysql到底有什么區(qū)別。于是今晚“谷歌”一番,整理一下。需要的朋友可以參考下。2011-08-08
完美解決MySQL通過(guò)localhost無(wú)法連接數(shù)據(jù)庫(kù)的問(wèn)題
下面小編就為大家?guī)?lái)一篇完美解決MySQL通過(guò)localhost無(wú)法連接數(shù)據(jù)庫(kù)的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
CentOS?7/8/9上安裝?MySQL?8.0+的方法完整指南
本文提供兩種在?CentOS?7/8/9?系統(tǒng)上安裝?MySQL?8.0?或更高版本的官方推薦方法,即使用?Yum?包管理器(適合新手)?和?手動(dòng)部署通用二進(jìn)制包(適合高級(jí)用戶(hù)),大家可以根據(jù)需要進(jìn)行選擇2025-11-11
MySQL的Data_ADD函數(shù)與日期格式化函數(shù)說(shuō)明
今天看到了MySQL的日期函數(shù),里面很多有用的,這里只把兩個(gè)參數(shù)不太好記的粘下來(lái)了。2010-06-06
mysql創(chuàng)建本地用戶(hù)及賦予數(shù)據(jù)庫(kù)權(quán)限的方法示例
這篇文章主要介紹了mysql創(chuàng)建本地用戶(hù)及賦予數(shù)據(jù)庫(kù)權(quán)限的相關(guān)資料,文中的介紹的非常詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-04-04
MySQL Version確認(rèn)問(wèn)題(版本確認(rèn))
這篇文章主要介紹了MySQL Version確認(rèn)問(wèn)題(版本確認(rèn)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12

