多表關聯查詢耗時 5s+,EXPLAIN 顯示 Using temporary; Using filesort,排序字段 published_at 有索引卻未被使用。優化器選擇 channels_news 作為驅動表(16 萬行),導致排序在臨時表進行。
SELECT * FROM news n0_
INNER JOIN news_translations n1_ ON n0_.id = n1_.translatable_id
INNER JOIN channels_news c3_ ON n0_.id = c3_.news_id
WHERE ... ORDER BY n0_.published_at DESC LIMIT 5;
| 階段 | 驅動表 | 掃描行數 | Extra | 耗時 |
|---|---|---|---|---|
| 優化前 | channels_news | 161,590 | Using temporary; Using filesort | 5s+ |
| 優化後 | news | 255,440 | Using where | 0.02s |
SELECT * FROM news n0_
STRAIGHT_JOIN news_translations n1_ ON n0_.id = n1_.translatable_id
STRAIGHT_JOIN channels_news c3_ ON n0_.id = c3_.news_id
WHERE ... ORDER BY n0_.published_at DESC LIMIT 5;
STRAIGHT_JOIN 強制按書寫順序連接,使 news 成為驅動表,排序直接利用索引,避免臨時表與 filesort。
ORDER BY 字段不在驅動表上時,需建立臨時表排序,產生巨大開銷。optimizer_switch。本案例中,STRAIGHT_JOIN 將查詢從 5s 降至 0.02s,展示了強制連接順序在特定場景下的威力,但務必以測試數據為準,避免過度優化。