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