核心差異一覽
| 特性 | UNION | UNION ALL |
| 重複行處理 | 排序去重,返回唯一結果集 | 直接合併,保留所有行(含重複) |
| 執行開銷 | 需排序 + 去重,可能落磁碟 | 單純串流合併,極快 |
| 適用場景 | 結果集可能重複,業務需去重 | 結果集天然不重複,或業務允許重複 |
實戰範例
場景:當前表與歷史表合併查詢
-- 業務邏輯:gc_dfys (當前) 與 ls_jg_dfys (歷史) 主鍵不重疊
-- 推薦:UNION ALL
SELECT * FROM gc_dfys UNION ALL SELECT * FROM ls_jg_dfys;
-- 若不確定是否有重複主鍵,或業務要求去重
SELECT * FROM gc_dfys UNION SELECT * FROM ls_jg_dfys;
效能實測參考
- 百萬級資料集,
UNION ALL 通常比 UNION 快 3-10 倍
UNION 觸發 filesort 時,臨時表可能寫入磁碟,I/O 開銷劇增
- 記憶體不足時
UNION 甚至會報錯 The table is full
決策流程圖
- 確認兩個結果集業務鍵是否可能重疊?
- 否 → 直接用 UNION ALL
- 是 → 業務是否要求去重?
- 是 → 用
UNION(接受效能代價)
- 否 → 用
UNION ALL,應用層處理或容忍重複
進階技巧
UNION ALL 子查詢可並行優化(MySQL 5.7+)
- 配合
LIMIT 下推:(SELECT ... LIMIT 10) UNION ALL (SELECT ... LIMIT 10) LIMIT 10
- 避免在
UNION 子查詢中使用 ORDER BY(無意義且消耗資源),只在最外層排序
總結
黃金法則:預設用 UNION ALL,除非明確需要去重且確認重複存在。這是 SQL 調優中「零成本、高收益」的首選優化。