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

MySQL STRAIGHT_JOIN 強制連接順序優化:解決 Using filesort 慢查詢實戰

     編輯:MySQL 資料庫相關知識

慢查詢現場

SELECT post.* FROM post
INNER JOIN post_tag ON post.id = post_tag.post_id
WHERE post.status = 1 AND post_tag.tag_id = 123
ORDER BY post.created DESC LIMIT 100;

EXPLAIN 對比

方案驅動表KeyRowsExtra
原始post_tagtag_id71,220Using where; Using filesort
STRAIGHT_JOINpoststatus_created119,340Using where

根因分析

優化器預設「結果集小的表做驅動表」。post_tag.tag_id=123 過濾後 7 萬行 < post.status=1 12 萬行,故選 post_tag 驅動。但 ORDER BY post.created 排序欄位不在驅動表,觸發 filesort。

STRAIGHT_JOIN 強制修正

SELECT post.* FROM post
STRAIGHT_JOIN post_tag ON post.id = post_tag.post_id
WHERE post.status = 1 AND post_tag.tag_id = 123
ORDER BY post.created DESC LIMIT 100;

強制以 post 為驅動表,利用 status_created 索引同時完成過濾與排序,避免 filesort。

適用場景與風險

  • ✅ 排序/分組欄位在非驅動表,且驅動表過濾度可接受
  • ✅ 統計資訊過期導致優化器誤判
  • ⚠️ 資料量變化大時,固定順序可能反而變慢
  • ⚠️ 非標準 SQL,移植性差

更優替代方案

  1. 複合索引:ALTER TABLE post ADD INDEX status_created (status, created DESC);
  2. 衍生表:先在子查詢中排序再 JOIN
  3. 更新統計:ANALYZE TABLE post, post_tag;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved