UNION 与 UNION ALL 的核心区别
主要差异对比表
| 特性 |
UNION |
UNION ALL |
|---|
| 重复数据处理 |
自动去重,返回唯一记录 |
保留所有记录,包括重复的 |
| 性能 |
较慢(需要排序和去重) |
较快(直接合并结果集) |
| 结果排序 |
默认不保证顺序,除非使用ORDER BY |
默认不保证顺序,除非使用ORDER BY |
| 语法 |
UNION |
UNION ALL |
详细解析
1.
重复数据处理
-- 示例数据
表A: 1, 2, 3, 4
表B: 3, 4, 5, 6
-- UNION: 去重
SELECT id FROM A
UNION
SELECT id FROM B
-- 结果: 1, 2, 3, 4, 5, 6 (7行)
-- UNION ALL: 保留所有
SELECT id FROM A
UNION ALL
SELECT id FROM B
-- 结果: 1, 2, 3, 4, 3, 4, 5, 6 (8行)
2.
性能影响
- UNION:需要进行额外的排序和去重操作,消耗更多资源
- UNION ALL:直接将结果集合并,效率更高
-- 性能测试示例
-- UNION ALL (推荐,如果不需要去重)
SELECT * FROM users_active
UNION ALL
SELECT * FROM users_inactive;
-- UNION (只有当需要去重时使用)
SELECT user_id FROM orders_2023
UNION
SELECT user_id FROM orders_2024;
3.
使用场景
使用 UNION ALL 的情况:
- 明确知道源表间没有重复数据
- 需要保留所有记录(包括重复的)
- 追求查询性能优化
- 例如:合并分区表数据
使用 UNION 的情况:
- 需要排除重复记录
- 统计唯一值
- 例如:获取去过不同城市的用户列表
4.
实际应用示例
-- 场景1:统计所有员工(包括在职和离职,可能有重复)
SELECT employee_id, name FROM current_employees
UNION ALL -- 可能有员工离职后又复职
SELECT employee_id, name FROM former_employees;
-- 场景2:获取不同的产品类别
SELECT category FROM products_electronics
UNION -- 确保类别不重复
SELECT category FROM products_furniture;
-- 场景3:分页查询合并(高效)
(SELECT id, name, created_at FROM table1 ORDER BY created_at DESC LIMIT 10)
UNION ALL
(SELECT id, name, created_at FROM table2 ORDER BY created_at DESC LIMIT 10)
ORDER BY created_at DESC LIMIT 10;
最佳实践建议
优先考虑 UNION ALL
- 大多数情况下,如果数据源本身不重复或重复可接受,使用UNION ALL
- 显著提升查询性能,特别是大数据量时
明确需求
- 是否需要去重?不需要 → 用UNION ALL
- 数据量大小?大表 → 优先UNION ALL
注意点
- 两个查询的列数必须相同
- 对应列的数据类型必须兼容
- ORDER BY 子句只能出现在整个语句的最后
性能对比示例
-- 假设每表有100万条数据
-- UNION: 需要处理200万条数据并去重
-- 执行时间: ~2.5秒
-- UNION ALL: 只需合并200万条数据
-- 执行时间: ~0.8秒
结论:除非明确需要去重,否则应优先使用 UNION ALL 以获得更好的性能。