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

MySQL 集合操作 UNION / UNION ALL 完全指南:語法、去重機制與性能優化

     編輯:MySQL 資料庫相關知識

集合操作將多個查詢結果垂直合併,MySQL 支援 UNION DISTINCT(去重)與 UNION ALL(保留重複)。本文通過建表、插數、實戰對比,詳細講解語法規則、內部實現機制、性能差異與選型建議。

一、準備工作:測試表與數據

CREATE TABLE table1 (
  aid INT NOT NULL AUTO_INCREMENT,
  title VARCHAR(20),
  tag VARCHAR(10),
  PRIMARY KEY (aid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE table2 (
  bid INT NOT NULL AUTO_INCREMENT,
  title VARCHAR(20),
  tag VARCHAR(10),
  PRIMARY KEY (bid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO table1 (title, tag) VALUES 
('article1','MySQL'), ('article2','PHP'), ('article3','CPP');

INSERT INTO table2 (title, tag) VALUES 
('article1','MySQL'), ('article2','CPP'), ('article3','C');

二、UNION DISTINCT(默認去重)

(SELECT * FROM table1) UNION (SELECT * FROM table2);

結果(5 行,重複行 1, article1, MySQL 僅保留一份):

aidtitletag
1article1MySQL
2article2PHP
3article3CPP
2article2CPP
3article3C

內部實現機制

  1. 創建內部臨時表(Memory/InnoDB)。
  2. 對所有列建立 唯一索引。
  3. 逐行插入,唯一索引自動過濾重複行(所有選擇列完全相同才視為重複)。
  4. 返回臨時表結果。

代價:唯一索引維護開銷、臨時表可能轉磁盤(大結果集),性能顯著低於 UNION ALL。

三、UNION ALL(保留所有行)

(SELECT * FROM table1) UNION ALL (SELECT * FROM table2);

結果(6 行,重複行完整保留):

aidtitletag
1article1MySQL
2article2PHP
3article3CPP
1article1MySQL
2article2CPP
3article3C

四、語法規則與注意事項

  • 列數、順序、類型兼容:各 SELECT 列數必須相同,對應位置類型隱式轉換兼容;結果列名以第一個 SELECT 為準。
  • ORDER BY / LIMIT:只能放在最後,或用括號包裹單獨 SELECT。
  • UNION DISTINCT 可簡寫為 UNION。

五、性能選型建議

場景推薦理由
確知兩集合無重複UNION ALL無唯一索引開銷,直接流式輸出,速度快數倍
需要業務去重UNION DISTINCT語義正確,避免應用層再次去重
大結果集(>10萬行)UNION ALL + 應用層去重避免臨時表轉磁盤、唯一索引膨脹
分頁顯示合併結果UNION ALL + 書簽分頁不需全量排序去重

六、總結

UNION = 去重合併(內部唯一索引),UNION ALL = 直接合併。默認優先使用 UNION ALL,只有在確需去重且結果集可控時才用 UNION。大數據場景建議將去重邏輯下推到應用層或使用分區表/物化視圖預聚合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved