一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

为什么在SQL视图中使用UNION ALL比UNION的执行效率更高

时间:2026-06-17 08:44:58 编辑:袖梨 来源:一聚教程网

UNION ALL比UNION快的根本原因是跳过去重+排序链路,纯流式拼接零临时表、零文件排序;UNION强制触发DISTINCT+ORDER BY,需临时结构、哈希/排序及可能磁盘I/O,100万行时慢11倍以上。

UNION ALL 在 SQL 视图中比 UNION 快,根本原因不是“少做了一步去重”,而是它跳过了整个去重+排序的数据处理链路——数据库压根不启动那套机制。


UNION 实际触发的是 DISTINCT + ORDER BY 两层开销

  • UNION 不是“先拼再筛”,而是强制走一套集合归并流程:所有子查询结果必须先写入临时结构(内存或磁盘),再做哈希/排序去重,最后按第一列升序输出(即使你没写 ORDER BY
  • 执行计划里常出现 Using temporaryUsing filesort,尤其当参与列无索引、数据量超 5 万行时,I/O 和 CPU 成为瓶颈
  • 即使你在外层加了 ORDER BY id,数据库仍可能执行两次排序:一次为去重,一次为你显式指定的顺序

UNION ALL 是纯流式拼接,零中间态

  • 它不做任何行级比较,不申请额外内存建哈希表,不写临时文件,也不调整顺序
  • 第一个 SELECT 开始返回数据,第二个紧接着追加,全程保持 pipeline 模式
  • EXPLAIN 看不到 Using temporaryUsing filesort,执行计划干净利落
  • 对于分表查询(如 log_202604log_202605)、状态互斥查询(如 status = 1status = 2),UNION ALL 的语义更准确、性能更可预期

列对齐和类型兼容性,两者要求完全一致

  • UNION ALL 并不宽容:列数不等、类型不兼容(比如 INTJSON)、NULL 性约束冲突(NOT NULL vs NULLable),一样报错
  • 别指望用 UNION ALL 绕过类型检查——MySQL 8.0+ 在严格模式下,第一条 SELECT 返回 NOT NULL VARCHAR(50),第二条返回 NULL,直接拒绝执行
  • 列名永远以第一个 SELECT 为准,后续子查询中的别名(如 SELECT id AS uid)无效

外层 ORDER BY 是唯一可控排序方式

  • 子查询里写 ORDER BY 没用,语法允许但被忽略;UNION 的隐式排序规则不可靠(可能按主键、也可能按表达式推导出的列),UNION ALL 更是完全依赖执行顺序
  • 正确写法只有一种:
    SELECT id, name FROM users_2023<br>UNION ALL<br>SELECT id, name FROM users_2024<br>ORDER BY id;
  • 少了这句,结果顺序在不同 MySQL 版本、不同执行路径下都可能变化,上线后容易引发前端渲染错乱或分页错位

真正容易被忽略的,是 UNION 的性能衰减是非线性的——100 万行时慢 11 倍,而嵌套在视图里再套一层 LIMIT OFFSET,代价可能翻倍还不止。

热门栏目