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

MySQL 複雜關聯查詢優化實戰:從 750ms 到 0ms 的四步法

     編輯:MySQL 綜合教學

MySQL 複雜關聯查詢優化實戰:從 750ms 到 0ms 的四步法

處理複雜關聯 SQL 優化,核心考量四點:

  1. 結果集極小(僅 1 筆),有優化信心
  2. 驅動表選擇關鍵,透過 EXPLAIN 觀察 rows 判斷瓶頸
  3. 理清表間關聯,確認關聯欄位有合適索引
  4. 用 STRAIGHT_JOIN 強制連接順序驗證假設

原始 SQL 與執行計劃

SELECT c.yh_id, c.yh_dm, c.yh_mc, c.mm, c.yh_lx,
       a.jg_id, a.jg_dm, a.jg_mc, a.jgxz_dm, d.js_dm yh_js
FROM a, b, c
LEFT JOIN d ON d.yh_id = c.yh_id
WHERE a.jg_id = b.jg_id
  AND b.yh_id = c.yh_id
  AND a.yx_bj = 'Y'
  AND c.sc_bj = 'N'
  AND c.yx_bj = 'Y'
  AND c.yh_dm = '006939748XX';

執行時間:**750 ms**,僅回傳 1 筆資料。

執行計劃瓶頸

+----+-------+------+------+----------------+------+--------+------+-------+-------------+
| id | table | type | key  | key_len | ref  | rows   | Extra        |
+----+-------+------+------+----------------+------+--------+------+-------+-------------+
| 1  | a     | ALL  | NULL | NULL     | NULL | 52,616 | Using where  |  ← 全表掃描
| 1  | d     | index| PRIMARY| 196   | NULL | 54,584 | Using index  |  ← 索引全掃描
+----+-------+------+------+----------------+------+--------+------+-------+-------------+

階段一:優化 LEFT JOIN 表 d

d 表無 yh_id 索引,導致 54,584 行掃描。新增索引:

ALTER TABLE d ADD INDEX ind_yh_id(yh_id);

結果:d 表掃描行數降至 **272 行**,但總時間 **0.77 秒** 未改善(a 表仍全掃)。

階段二:嘗試以 c 表為驅動表

c 表有高選擇性條件 yh_dm = '006939748XX'(僅 2 筆),新增索引:

ALTER TABLE c ADD INDEX ind_yh_dm(yh_dm);

但優化器仍選 a 表為驅動表。分析原因:

  • c → b 關聯需 b.yh_id 索引,但 b 表無此索引,b 表大(105,809 行)
  • a → b 關聯有 b.jg_id 索引(主鍵包含),優化器判斷成本較低

階段三:補齊關鍵索引,強制最佳路徑

ALTER TABLE b ADD INDEX ind_yh_id(yh_id);

再次執行,執行計劃變為:

c (ref, rows=2) → d (ref, rows=272) → b (ref, rows=531) → a (eq_ref, rows=1)

**執行時間:0.00 秒(< 1ms)**,較原始 **提升 750 倍**。


核心心得

步驟動作效果
1 分析 EXPLAIN 找出大 rows 的表 定位瓶頸
2 為高選擇性條件欄位建索引 降低驅動表掃描量
3 補齊關聯欄位索引(特別是被驅動表) 讓優化器選擇最佳連接順序
4 必要時用 STRAIGHT_JOIN/FORCE INDEX 驗證 確認最優路徑
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved