- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業(yè)務(wù)經(jīng)營許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯(lián)網(wǎng)協(xié)會理事單位
- 安全聯(lián)盟認(rèn)證網(wǎng)站身份V標(biāo)記
- 域名注冊服務(wù)機(jī)構(gòu)許可:滇D3-20230001
- 代理域名注冊服務(wù)機(jī)構(gòu):新網(wǎng)數(shù)碼
歡迎來到藍(lán)隊云技術(shù)小課堂,每天分享一個技術(shù)小知識。
EXPLAIN 是 MySQL 提供的一種強(qiáng)大的工具,用于分析 SQL 查詢的執(zhí)行計劃。它能夠幫助我們了解查詢是如何執(zhí)行的,從而發(fā)現(xiàn)潛在的性能瓶頸,并采取優(yōu)化措施。通過 EXPLAIN 返回的信息,我們可以判斷索引是否被正確使用,查詢是否存在不必要的全表掃描,是否存在其他影響性能的操作。下面是 EXPLAIN 的詳細(xì)使用方法和如何根據(jù)返回的結(jié)果優(yōu)化查詢。
要使用 EXPLAIN,只需在你想分析的 SELECT 語句前加上 EXPLAIN 關(guān)鍵字。例如:
EXPLAIN SELECT * FROM your_table WHERE your_column = 'your_value';
執(zhí)行后,MySQL 會返回查詢的執(zhí)行計劃,幫助你分析查詢的性能。
EXPLAIN 命令返回的結(jié)果集包含以下列,它們提供了查詢執(zhí)行的詳細(xì)信息:
列名 | 說明 |
id | 查詢中的每個 SELECT 子句的標(biāo)識符,簡單查詢通常是 1,子查詢的 id 從 2 開始。 |
select_type | 查詢類型,常見的有:SIMPLE(簡單查詢)、PRIMARY(最外層查詢)、UNION(UNION 查詢)、SUBQUERY(子查詢)、DERIVED(派生表)。 |
table | 當(dāng)前操作涉及的表。 |
type | 連接類型,常見的有:ALL(全表掃描)、range(范圍掃描)、ref(通過索引查找匹配行)、eq_ref(每行匹配唯一行)。 |
possible_keys | 查詢中可能使用的索引。 |
key | 實際使用的索引。如果沒有使用索引,顯示 NULL。 |
key_len | 使用的索引的長度(字節(jié)數(shù))。 |
ref | 顯示使用哪個列或常量與 key 一起從表中選擇行。 |
rows | MySQL 估計查詢需要掃描的行數(shù)。 |
Extra | 額外的信息,常見的有:Using where(使用 WHERE 篩選行)、Using index(只使用索引,無需掃描表)、Using temporary(使用臨時表)、Using filesort(使用文件排序)。 |
· SIMPLE:簡單查詢,不包含子查詢或 UNION。
· PRIMARY:最外層的查詢。
· UNION:UNION 查詢的第二個及后續(xù)查詢。
· SUBQUERY:子查詢中的第一個 SELECT 查詢。
· DERIVED:派生表的查詢。
· const:只掃描一行,常見于主鍵或唯一索引查詢。
· eq_ref:每個來自前一表的行,聯(lián)合查詢時每次讀取一行。
· ref:通過索引查找匹配的行,適用于非唯一索引。
· range:掃描索引的某個范圍,效率較高。
· index:全索引掃描,按索引順序讀取。
· ALL:全表掃描,通常是效率最差的訪問方式。
假設(shè)我們有以下查詢:
EXPLAIN SELECT u.user_id, u.name, o.order_idFROM users uJOIN orders o ON u.user_id = o.user_idWHERE u.status = 'active' AND o.order_date > '2024-01-01';
執(zhí)行計劃可能返回如下結(jié)果:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1 | SIMPLE | u | ref | PRIMARY | PRIMARY | 4 | const | 5 | Using where |
1 | SIMPLE | o | ref | user_id | user_id | 4 | database.u.user_id | 10 | Using where |
· id:查詢中只有一個 SELECT 語句,因此 id 為 1。
· select_type:查詢類型為 SIMPLE,表示沒有子查詢。
· table:查詢的是 users(u)和 orders(o)表。
· type:users 表使用了 ref 類型的連接方式,orders 表也使用了 ref 類型,意味著都通過索引查找匹配的行。
· possible_keys:users 表的可能索引是 PRIMARY(假設(shè) user_id 是主鍵),orders 表的可能索引是 user_id。
· key:users 表實際使用了 PRIMARY 索引,orders 表使用了 user_id 索引。
· rows:users 表預(yù)計需要讀取 5 行,orders 表預(yù)計需要讀取 10 行。
· Extra:顯示 Using where,表示查詢會根據(jù) WHERE 子句進(jìn)行篩選。
通過 key 列可以確認(rèn)查詢是否使用了索引。如果 key 為 NULL,則表示沒有使用索引,這時需要考慮為查詢的字段添加索引,或者優(yōu)化查詢邏輯。
type 列顯示了查詢的連接方式,ALL 類型表示全表掃描,這是最不理想的情況。為了提高性能,應(yīng)該盡量避免 ALL,可以通過創(chuàng)建合適的索引來避免全表掃描。
rows 列顯示了 MySQL 估計的掃描行數(shù),如果行數(shù)過多,查詢的性能可能較差。此時可以考慮優(yōu)化查詢條件、增加索引或者重寫查詢語句。
Extra 列如果顯示 Using temporary 或 Using filesort,表示查詢需要創(chuàng)建臨時表或進(jìn)行額外的排序操作,這可能會嚴(yán)重影響查詢性能。盡量避免這些操作,可以通過優(yōu)化查詢、調(diào)整索引或重新設(shè)計查詢來減少臨時表的使用。
假設(shè)我們有一個查詢沒有使用索引:
EXPLAIN SELECT * FROM users WHERE name = 'John Doe';
返回結(jié)果:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 100000 | Using where |
· type 是 ALL,表示全表掃描。
· key 為 NULL,表示沒有使用索引。
優(yōu)化方案:
CREATE INDEX idx_name ON users(name);
執(zhí)行優(yōu)化后的查詢:
EXPLAIN SELECT * FROM users WHERE name = 'John Doe';
返回結(jié)果:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1 | SIMPLE | users | ref | idx_name | idx_name | 102 | const | 1 | Using where |
· type 變?yōu)?/span> ref,表示索引查詢。
· key 變?yōu)?/span> idx_name,表示查詢使用了新建的索引。
· 通過這種優(yōu)化,查詢性能顯著提高。
EXPLAIN 是優(yōu)化 MySQL 查詢的一個重要工具,它能夠幫助我們深入了解查詢的執(zhí)行過程,識別潛在的性能問題。通過 EXPLAIN 返回的各列信息,我們可以判斷查詢是否高效,是否合理使用了索引,是否有不必要的全表掃描,是否存在文件排序或臨時表的使用等。通過合理地使用索引、優(yōu)化查詢條件和連接方式,可以有效提升查詢性能。
藍(lán)隊云官網(wǎng)上擁有完善的技術(shù)支持庫可供參考,大家可自行查閱,更多技術(shù)問題,可以直接咨詢。同時,藍(lán)隊云整理了運維必備的工具包免費分享給大家使用,需要的朋友可以直接咨詢。
提交成功!非常感謝您的反饋,我們會繼續(xù)努力做到更好!
這條文檔是否有幫助解決問題?
售前咨詢
售后咨詢
備案咨詢
二維碼
TOP