UNION ALL 与 UNION 的核心区别在于前者不排序、不去重、性能更高,而后者会隐式去重排序;使用时须确保列数一致、类型兼容、ORDER BY 和 LIMIT 仅能置于末尾,且需警惕大结果集引发的临时表与内存问题。
UNION ALL 和 UNION 的区别到底在哪
用
是为了不丢数据、不排序、不去重,性能比
高一截。如果你两个查询结果里天然没重复(比如查不同日期的订单、不同状态的用户),硬用
反而多一次隐式去重扫描,白耗 CPU 和临时空间。
常见错误现象:
后字段顺序对不上,MySQL 直接报错
;或者字段类型隐式转换失败,比如一边是
,一边是
,MySQL 尝试转但精度丢失或截断。
列数必须完全一致 —— 不是“看起来差不多”,是 SELECT 后面显式写出的字段个数
对应位置的字段类型最好一致;若不一致,MySQL 会按「更宽泛类型」隐式转换(如
和
会转成
),但
和
没问题,
和
就大概率出错
列名以第一个
的为准,后面语句的 AS 别名不影响最终列名
字段对齐时最容易漏掉的三件事
很多人写完两个 SELECT 就直接加
,运行报错才回头找——其实问题基本就出在字段对齐上。
SELECT 列表里不能有“多一个少一个”的字段:比如第一个查
,第二个就不能只写
或多加个
,得补
或
函数返回值类型要小心:
是
,
是
,混在一起可能触发隐式转换警告甚至截断
聚合查询和非聚合查询不能直接拼:
和
列数、语义都不匹配,得先统一成同结构(比如都带
,COUNT 结果作为一列)
ORDER BY 和 LIMIT 只能放在最后
是集合操作,不是子查询嵌套,所以中间每个 SELECT 不能单独加
或
(MySQL 8.0.22+ 允许单个子句加,但意义不大,且容易误导)。
常见错误现象:写成
,MySQL 报错或忽略前面的
,最终结果乱序、数量也不对。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
真要限制总数,只能在整个
外再套一层
真要全局排序,
必须写在最后,且只能引用最终列名或位置(如
表示第一列)
如果某一边需要“取最新一条”,得提前用窗口函数或子查询处理好,再参与
大结果集合并时的内存与临时表风险
本身不排序不去重,看似轻量,但如果两边结果都很大(比如各 50 万行),MySQL 还是得把全部结果暂存在内存或磁盘临时表里,才能返回给客户端。
典型表现:查询变慢、
和
状态变量飙升、甚至触发
或
限制导致报错
。
确认是否真需要一次性拉全量:前端分页?那就该在应用层分别查、再合并逻辑,而不是全扔给 MySQL
检查执行计划:
看
是否为
,
有没有
—— 如果有,说明已落地磁盘临时表
避免在
中使用未索引字段排序或 GROUP BY,这会让优化器更倾向走临时表
字段类型不一致、列数不对、ORDER BY 放错位置、临时表撑爆内存——这四点占了实际开发中 90% 的
问题。调的时候别急着改语法,先
看执行计划,再逐条核对字段定义。
UNION ALLUNIONUNIONUNIONERROR 1222 (21000): The used SELECT statements have a different number of columnsINTVARCHARINTDECIMALDECIMALVARCHAR(10)VARCHAR(100)TINYINTDATETIMESELECTUNION ALLid, name, created_atid, namesourceNULL AS created_at'static' AS sourceNOW()DATETIMECURDATE()DATESELECT user_id FROM ordersSELECT COUNT(*) FROM orders GROUP BY user_iduser_idUNION ALLORDER BYLIMIT(SELECT ... ORDER BY id LIMIT 10) UNION ALL (SELECT ... ORDER BY id LIMIT 10)ORDER BYUNION ALLSELECT * FROM (...) AS t LIMIT 20ORDER BYORDER BY 1UNION ALLUNION ALLCreated_tmp_tablesCreated_tmp_disk_tablesmax_heap_table_sizetmp_table_sizeERROR 1105 (HY000): Out of memoryEXPLAINtypeALLExtraUsing temporaryUNION ALLUNION ALLEXPLAIN