首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL SQL 優化實戰:EXPLAIN 與 PROFILE 深度解析與索引最佳實踐

     編輯:MySQL 資料庫相關知識

核心工具介紹

  • EXPLAIN: 查詢執行計劃,揭示優化器如何訪問表、使用索引、聯接順序。必會技能。
  • PROFILE (SHOW PROFILE/PROFILES): 會話級性能剖析,細粒度展示各階段耗時 (解析、優化、執行、發送數據等)。MySQL 5.7+ 棄用,建議用 Performance Schema 替代。

實戰案例:索引對查詢路徑的決定性影響

環境準備


CREATE TABLE tt (id INT PRIMARY KEY, name CHAR(20)) ENGINE=InnoDB;
CREATE TABLE ttt (id INT, name CHAR(20)) ENGINE=InnoDB;  -- 無主鍵/索引
INSERT INTO tt VALUES (1,'aaa'),(2,'bbb'),(3,'ccc');
INSERT INTO ttt VALUES (1,'aaa'),(2,'bbb'),(3,'ccc');

案例 1:主鍵範圍查詢


EXPLAIN SELECT * FROM tt WHERE id > 1;

輸出關鍵列解讀:

列值含義
typerange索引範圍掃描,優於 ALL (全表掃描)
possible_keysPRIMARY可用索引
keyPRIMARY實際使用索引
key_len4索引鍵長度 (INT=4 字節)
rows2預估掃描行數 (優化器統計信息)
ExtraUsing where需在存儲引擎層過濾 WHERE 條件

結論: 有主鍵索引,優化器直接定位滿足條件的 2 行,極高效。

案例 2:無索引表全表掃描


EXPLAIN SELECT * FROM ttt WHERE id > 1;

關鍵差異: type=ALL、key=NULL、rows=3。全表掃描 3 行。若表為 GB 級,IO/CPU 開銷災難性。

案例 3:非索引列查詢 (即使有主鍵)


EXPLAIN SELECT * FROM tt WHERE name = 'aaa';

結果: type=ALL、rows=3。雖只有 1 行結果,但無 name 索引,仍需全表掃描。

PROFILE 實戰剖析 (教學演示,生產建議用 Performance Schema)


SET profiling = 1;
SELECT * FROM tt;
SHOW PROFILE;
SHOW PROFILES;

典型階段耗時解讀:

  • Sending data:0.000148s — 數據傳輸佔比大,網絡/結果集大小敏感
  • Opening tables、Table lock:微秒級,若偏高檢查 table_open_cache/鎖爭用
  • optimizing、statistics:優化器成本,復雜聯接時關注

SHOW PROFILES 歷史記錄: 可對比不同 SQL 總耗時,快速定位慢查詢。

索引設計黃金法則

  1. 左前綴原則: 聯合索引 (a,b,c) 支持 a、a,b、a,b,c,不支持 b、c、b,c
  2. 高選擇性優先: 區分度高 (唯一值/總行數 > 0.1) 的列放前面
  3. 覆蓋索引: SELECT a,b FROM tbl WHERE c=1 → 索引 (c,a,b) 避免回表
  4. 避免索引失效: 函數操作 (WHERE YEAR(dt)=2024)、隱式轉換 (WHERE phone=13800000000 但 phone 是 VARCHAR)、!=/NOT IN/LIKE '%abc'
  5. 主鍵設計: 單調遞增 (AUTO_INCREMENT/BIGINT),非業務字段,盡量短

EXPLAIN 關鍵列速查表

列名核心關注點優化方向
typesystem > const > eq_ref > ref > range > index > ALL至少達到 range,最好 ref/eq_ref
key實際用索引NULL 表示無索引可用,需建索引
key_len索引鍵長度推斷聯合索引用了幾列
rows預估掃描行數越小越好,InnoDB 為估算值
ExtraUsing index/where/filesort/temporaryUsing index 好;filesort/temporary 需優化

避坑指南

  • EXPLAIN 不執行 DML: 不會修改數據,放心用於生產
  • 統計信息準確性: ANALYZE TABLE 更新統計,InnoDB 抽樣 8 頁,大表可能不準
  • Profile 替代方案: MySQL 8.0 使用 sys.statement_analysis、performance_schema.events_statements_summary_by_digest
  • 慢查詢日志聯動: long_query_time=1 + log_queries_not_using_indexes=ON,配合 pt-query-digest 分析

總結

SQL 優化的本質是「讓優化器找到最優路徑」。EXPLAIN 是眼睛,索引是腿,統計信息是地圖。掌握 type、key、rows、Extra 四大核心指標,結合左前綴、覆蓋索引、選擇性原則,90% 的慢查詢可通過加索引/改寫 SQL 解決。剩下 10% 需架構層面:分庫分表、讀寫分離、緩存策略、異步處理。

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