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

MySQL SQL 優化核心原則與實戰案例:索引、類型、EXPLAIN 避坑全指南

     編輯:MySQL 資料庫相關知識

黃金法則:索引是查詢加速器,也是寫入負擔

優化口訣:「該建必建、精準前綴、覆蓋優先、拒絕過度」

12 條核心原則速查表

#原則關鍵動作反模式
1用索引加速遍歷高選擇性列建索引;範圍查詢/排序/分組列考慮聚簇索引全表掃描成常態
2組合索引最左前綴WHERE/Order By/Group By 列順序與索引列順序一致索引列順序顛倒導致失效
3覆蓋索引避免回表SELECT 列 ⊆ 索引列,Extra=Using indexSELECT * 強制回表
4列運算殺死索引WHERE col + 1 = 10 → WHERE col = 9函數/運算/隱式轉換包裹索引列
5IN/OR 謹慎使用IN 值集小可用;OR 改 UNION ALL + 索引大 IN 列表 / OR 跨列無索引
6小類型大智慧MEDIUMINT 代替 INT;NOT NULL 默認;ENUM 代替 VARCHAR 低基數BIGINT 存布爾/狀態碼
7拒絕 VARCHAR/TEXT/BLOB 當主鍵/索引前綴過長主鍵用自增 BIGINT/UUID_SHORT;前綴索引長度夠區分即可VARCHAR(255) 主鍵 + 全長索引
8EXPLAIN 驗證每條慢查詢關注 type、key、rows、Extra (Using filesort/temporary)裸跑上線再看慢查詢日志
9多表 JOIN 索引策略驅動表小、被驅動表 JOIN 列有索引;Redundant 索引清理大表驅動小表、被驅動表無索引
10索引維護成本核算寫多讀少表減少索引;批量導入先 Drop Index 後重建單表 20+ 索引,INSERT 狂慢
11前綴索引長度科學計算SELECT COUNT(DISTINCT LEFT(col, N))/COUNT(*) 從 0.9 起步隨意索引前 10 字符
12慢查詢日志 + pt-query-digest 定期複盤長期觀察 Top 10 慢查詢,針對性優化只看當下不看趨勢

實戰基準測試:索引前後對比 (3.7 萬行 users 表)


-- 無索引
SELECT * FROM users WHERE username LIKE '%許%';  -- 0.54s 平均
SELECT * FROM users WHERE username LIKE '許%';   -- 0.53s 平均
SELECT * FROM users WHERE username LIKE '%許';   -- 0.51s 平均

-- 建立前綴索引 (username 前 6 字符)
CREATE INDEX idx_username_prefix ON users(username(6));

-- 有索引
SELECT * FROM users WHERE username LIKE '%許%';  -- 0.34s (提升 37%)
SELECT * FROM users WHERE username LIKE '許%';   -- 0.065s (提升 88% !!!)
SELECT * FROM users WHERE username LIKE '%許';   -- 0.31s (提升 39%)

結論:前綴索引對 **左前綴匹配 (`LIKE 'prefix%'`)** 提升毀滅性;對 `%中間%`、`%後綴` 提升有限,需全文索引或架構調整 (如 Elasticsearch)。

多表 JOIN 索引實戰


-- 場景:訂單 100萬 + 用戶 10萬,查詢某用戶最近 20 條訂單
-- 錯誤:orders 無 user_id 索引
EXPLAIN SELECT * FROM orders o JOIN users u ON o.user_id = u.id WHERE u.id = 1001 ORDER BY o.created_at DESC LIMIT 20;
-- type=ALL, rows=1000000

-- 正確:orders(user_id, created_at) 組合索引
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at);
-- type=ref, rows=20 (索引下推 + 排序已滿足)

避坑清單:常見索引失效場景

  1. 隱式類型轉換:`WHERE varchar_col = 123` → 全表掃描。修正:`WHERE varchar_col = '123'`。
  2. != / NOT IN / NOT EXISTS:通常不走索引。改用 `LEFT JOIN ... WHERE b.id IS NULL`。
  3. LIKE 以 % 開頭:`LIKE '%abc'` 無法利用 B+Tree 有序性。
  4. 複合索引列順序錯誤:`INDEX(a,b)` 查 `WHERE b=1` 不走索引。
  5. OR 跨列:`WHERE a=1 OR b=2` (a,b 單列有索引) → 全表掃描。改 `UNION ALL`。

總結

SQL 優化無銀彈,**「EXPLAIN 驗證假設 → 最小化掃描行數 → 平衡讀寫成本」** 是唯一科學路徑。將 12 條原則印成卡片貼在工位,每次寫慢查詢前過一遍,半年內必成優化高手。

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