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

MySQL 複雜多表關聯優化:驅動表選擇與 straight_join 實戰

     編輯:MySQL 資料庫相關知識

優化四大原則

  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.sc_bj = 'N'
  AND c.yh_dm = '006939748XX';

耗時 750ms,EXPLAIN 顯示兩大瓶頸:

  • a 表 type=ALL 掃描 52,616 行
  • d 表 type=index 全索引掃描 54,584 行

階段優化過程

第一階段:為 d 表加索引

ALTER TABLE d ADD INDEX ind_yh_id(yh_id);

d 表掃描行數 54,584 → 272,但總耗時 770ms 未改善(驅動表仍是 a)。

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

ALTER TABLE c ADD INDEX ind_yh_dm(yh_dm);

優化器仍選 a 驅動,因 b 表無 yh_id 索引,關聯代價大。

第三階段:補齊 b 表索引,成功切換驅動表

ALTER TABLE b ADD INDEX ind_yh_id(yh_id);

最終執行計劃:

+----+-------------+-------+------+----------------+-----------+---------+----------+------+-------------+
| id | select_type | table | type | possible_keys  | key       | key_len | ref      | rows | Extra       |
+----+-------------+-------+------+----------------+-----------+---------+----------+------+-------------+
| 1  | SIMPLE      | c     | ref  | ind_yh_dm      | ind_yh_dm | 57      | const    | 2    | Using where |
| 1  | SIMPLE      | d     | ref  | ind_yh_id      | ind_yh_id | 98      | c.yh_id  | 272  | Using index |
| 1  | SIMPLE      | b     | ref  | ind_yh_id      | ind_yh_id | 98      | c.yh_id  | 531  | Using index |
| 1  | SIMPLE      | a     | eq_ref| PRIMARY       | PRIMARY   | 98      | b.jg_id  | 1    | Using where |
+----+-------------+-------+------+----------------+-----------+---------+----------+------+-------------+

耗時:0.00 秒(750ms → <1ms)。

核心心法

  • 驅動表應為「過濾後行數最少」的表
  • 關聯鏈路每一環都需有索引支援
  • STRAIGHT_JOIN 是驗證假設的利器,生產慎用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved