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

MySQL SQL 優化實戰:關聯子查詢效能陷阱與改寫策略

     編輯:MySQL 資料庫相關知識

業務系統頻繁出現執行 286~480 秒的慢 SQL,統計發現外層表 t1 掃描 90 萬列,根因是 MySQL 優化器將關聯子查詢的外層表「下推」到子查詢內部,導致大表全掃描。本文剖析優化器局限性與改寫方案。

問題 SQL 模型

SELECT * FROM t1
WHERE col1 IN (SELECT col2 FROM t2 WHERE t2.id = t1.id);

MySQL 會將 t1 逐列代入子查詢執行,等同於 Nested Loop Join,若 t1 為大表則災難性。

優化器行為分析

  • MySQL 5.6/5.7 對 IN/EXISTS 關聯子查詢優化有限,無法自動轉為 Semi-Join 或 Materialization。
  • EXPLAIN 會顯示 DEPENDENT SUBQUERY,rows 接近外層表全量。

改寫策略與效果

驗證指標

  • 優化前:12 次執行,最長 480s,掃描 90 萬列。
  • 優化後:執行時間降至 0.5s 內,掃描列數 < 1000。

核心心法:大表關聯子查詢優先考慮 JOIN 或 物化表,配合適當索引,避開優化器「下推」陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案SQL 範例原理效果
JOIN 改寫SELECT t1.* FROM t1 JOIN t2 ON t1.id=t2.id WHERE t1.col1=t2.col2;優化器可選擇 Hash Join / Index Join秒級完成
導出表SELECT * FROM t1 JOIN (SELECT DISTINCT col2,id FROM t2) dt ON t1.id=dt.id WHERE t1.col1=dt.col2;物化子查詢結果集大幅降低掃描
增加索引ALTER TABLE t2 ADD INDEX idx_col2_id (col2,id);支援 Index Lookup輔助上述方案