首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 索引與性能分析實戰:EXPLAIN、慢查詢、索引優化核心指標

     編輯:MySQL 綜合教學

MySQL 索引與性能分析實戰

索引是 MySQL 查詢性能的核心杠桿。本文系統梳理 EXPLAIN 輸出字段含義、慢查詢日誌分析、索引設計原則 (最左前綴、覆蓋索引、回表)、常見反模式及優化檢查清單,幫助開發者從「能跑」走向「跑得快」。

1. EXPLAIN 深度解讀

EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 1;

列名含義關注重點
id查詢序號,標識執行順序相同 id 從上到下執行;id 越大優先級越高
select_type查詢類型SIMPLE (無子查詢/UNION)、PRIMARY (最外層)、SUBQUERY、DERIVED (衍生表)、UNION
table訪問的表 (或衍生表別名)確認是否掃描預期表
partitions匹配的分區 (分區表)檢查分區裁剪是否生效
type訪問類型 (核心指標)從好到壞:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL (全表掃描)。
目標:至少達到 ref,避免 ALL/index。
possible_keys可能用到的索引為空說明無可用索引,需建立
key實際使用的索引若為 NULL 則未用索引
key_len索引鍵長度 (字節)越短越好;推斷聯合索引用了幾列 (如 INT=4, VARCHAR(20) UTF8=60+2)
ref與索引比較的列或常量const 表示常量,列名表示關聯查詢
rows預估掃描行數越小越好;與實際行數偏差大時需 ANALYZE TABLE
filtered按條件過濾後剩餘行數百分比越高越好;低說明索引列選擇性差
Extra額外信息 (關鍵優化線索)好:Using index (覆蓋索引)、Using where (Server 層過濾)。
壞:Using filesort (需排序)、Using temporary (臨時表)、Using join buffer (Join Buffer)、Impossible WHERE (條件永假)。

2. 索引設計鐵律

  • 最左前綴原則:聯合索引 (a,b,c) 僅當查詢條件包含 a、a,b、a,b,c (順序不限,優化器會重排) 時生效;b、c、b,c 不走索引。
  • 覆蓋索引:SELECT a,b FROM t WHERE c=1 配合索引 (c,a,b),Extra 顯示 Using index,避免回表,極大提升性能。
  • 選擇性:COUNT(DISTINCT col)/COUNT(*) 越接近 1 越適合建索引;性別、狀態等低選擇性列單列索引無效。
  • 前綴索引:長字符串列建索引指定長度 INDEX(name(10)),平衡大小與選擇性。
  • 避免索引失效:!=/<>、IS NULL/IS NOT NULL、LIKE '%abc' (前導通配)、隱式類型轉換 (WHERE varchar_col = 123)、對索引列運算 (WHERE YEAR(date_col)=2023)、OR 條件兩側索引不一致。

3. 慢查詢日誌分析流程

  1. 開啟:slow_query_log=ON, long_query_time=1 (秒), log_queries_not_using_indexes=ON。
  2. 分析工具:pt-query-digest (Percona Toolkit) 聚合統計、按響應時間/頻率/掃描行排序 Top N。
  3. 優化閉環:定位 Top SQL → EXPLAIN 分析 → 調整索引/重寫 SQL/調整參數 → 驗證效果 → 固化變更。

4. 常見性能殺手與對策

現象根因對策
全表掃描 (type=ALL)無索引、索引失效、小表優化器選擇掃描建立合適索引、強制索引 FORCE INDEX、重寫 SQL
Using filesortORDER BY 列無索引、聯合索引順序不符、方向混用 (ASC/DESC)建立排序列索引、調整索引列順序、MySQL 8.0 降序索引
Using temporaryGROUP BY/DISTINCT 無索引、UNION、JOIN 產生臨時表索引覆蓋 GROUP BY 列、避免不必要 DISTINCT
回表過多非覆蓋索引查詢需回主鍵索引取列構建覆蓋索引、只查主鍵再關聯、冗余列
鎖爭用/死鎖大事務、索引缺失導致鎖升級、死鎖循環等待拆分大事務、補全索引、固定加鎖順序、降低隔離級別

5. 索引維護檢查清單 (月度/上線前)

  • [ ] SHOW INDEX FROM tbl 檢查重複/冗余索引 (如 PRIMARY KEY(id) + INDEX(id))。
  • [ ] SELECT * FROM sys.schema_unused_indexes (MySQL 5.7+ sys schema) 找出長期未用索引並刪除。
  • [ ] ANALYZE TABLE 更新統計信息,修正優化器誤判。
  • [ ] 監控 Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests 命中率 > 99%。
  • [ ] 關鍵業務 SQL 納入自動化 EXPLAIN 回歸測試,防止版本迭代引入性能退化。

EXPLAIN 輸出示例 索引結構示意 慢查詢分析圖 優化前後對比

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved