萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL UNION 多表查詢實戰:欄位不一致時的對齊技巧與效能優化

UNION 基本語法

SELECT col1, col2 FROM table1 WHERE condition
UNION [ALL]
SELECT col1, col2 FROM table2 WHERE condition;
  • UNION:去重(預設),需排序比較,較慢
  • UNION ALL:保留重複,直接合併結果集,**效能高得多**,無去重需求時優先使用

核心限制:欄位數量、順序、型別必須一致

若兩表結構不同,直接 UNION 會報錯:The used SELECT statements have a different number of columns。

解決方案:佔位符對齊欄位

場景:table1 有 4 欄位,table2 僅 2 欄位

SELECT password, username, email, ip
FROM table1
WHERE username LIKE '123'

UNION ALL

SELECT password, username, '', ''  -- 用空字串佔位 email、ip
FROM table2
WHERE username LIKE '123';

進階:型別對齊與預設值

SELECT id, name, email, created_at, status
FROM users_old
WHERE status = 1

UNION ALL

SELECT id, name, email, created_at, 1 AS status  -- 新表無 status,給預設值 1
FROM users_new
WHERE is_active = 1;

動態欄位:使用 NULL 佔位

SELECT col_a, col_b, col_c, col_d
FROM table_a

UNION ALL

SELECT col_a, col_b, NULL AS col_c, NULL AS col_d
FROM table_b;

建議: 明確指定別名(AS col_c),避免驅動程式映射錯誤。

效能優化關鍵點

  1. 優先用 UNION ALL:除非業務必須去重
  2. 子查詢加 LIMIT:(SELECT ... LIMIT 1000) UNION ALL (SELECT ... LIMIT 1000) 避免全表掃描
  3. 確保 WHERE 條件命中索引:各子查詢獨立優化
  4. 避免 ORDER BY 在外層:會導致臨時表 + filesort,改用子查詢各自排序
  5. 大資料量考慮分頁查詢改寫:UNION ALL 不支援 LIMIT offset, rows 高效分頁,需應用層游標式分頁

UNION vs UNION ALL 效能實測(100 萬行)

操作耗時臨時表排序
UNION3.2s是filesort
UNION ALL0.4s否無

替代方案

  • VIEW: 將 UNION 封裝為視圖,簡化應用層 SQL
  • MERGE 表: MyISAM 專用,邏輯合併同結構表(不支援 InnoDB)
  • 分區表: 原生支援範圍/雜湊分區,查詢自動裁剪分區
  • 應用層合併: 並行查詢多表,記憶體合併排序
copyright © 萬盛學電腦網 all rights reserved