MySQL的select distinct ..Union all和select..union的区别

union和union all去重SQL真实案例

以下是真实的生产业务SQL,我只是把表名更换了一下:(就是捞取两张表的两列数据再去重)

sql 复制代码
SELECT DISTINCT user_id, user_name
FROM (
    SELECT DISTINCT
           manager_id AS user_id,
           manager_name AS user_name
    FROM demo_order_detail
    WHERE status = 1

    UNION ALL

    SELECT DISTINCT
           operator_id AS user_id,
           operator_name AS user_name
    FROM demo_task
    WHERE status = 1
) t;

上面的SQL中,用了union all,那么我们用两个测试表看一下select distinct union all和直接用select union它们的执行过程树形图是什么样的:

只有select union的SQL场景

他的过程是:

sql 复制代码
user
 ↓
recharge
 ↓
边合并边物化,并在这个 UNION 结果层完成去重

select distinct union all的SQL场景

他的过程是:

sql 复制代码
user
 ↓
recharge
 ↓
先全部 UNION ALL
 ↓
形成完整的 t
 ↓
再扫描 t
 ↓
重新建临时表
 ↓
最后 DISTINCT 去重

数据量很小的时候,这两种SQL的差异是很难凸现出来的,那么我们试一下更大的百万级数据量。

百万计数据量时,两种性能的对比

测试表结构:

sql 复制代码
-- 用户表
CREATE TABLE user (
    id INT PRIMARY KEY,
    name VARCHAR(20)
);


-- 用户充值表
CREATE TABLE recharge (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    KEY idx_user_id (user_id)
);

我们先看下表数据量(100万用户,300万条充值流水):

分别explain看执行计划

只有union的过程

sql 复制代码
recharge 300万
↓
idx_user_id 覆盖索引扫描
↓
第一次去重
300万 → 10万
↓
UNION ALL
↓
最终 DISTINCT
↓
100万

这个执行过程生成耗时4.35s

union al加distinct的过程

sql 复制代码
user 100万
       \
        UNION ALL
       /
recharge 300万
↓
中间结果约 400万
↓
再做一次最终 DISTINCT
↓
100万

生成执行计划耗时9.44秒,明显比直接union的慢了不少。

再看下他们的真实SQL执行上差距,防止内存或者磁盘溢出,我直接通过count(*)来对比他们的性能:

由此可见,百万数量级直接union的性能比union all distinct的高大概30%。

把recharge充值表数据量提高到千万级别select尝试:

依然是快了30%左右,这绝对是非常实用的一个优化点!

相关推荐
九零HTTP16 分钟前
10月21号-CSDN配菜-IP池的5个坑
服务器·数据库·tcp/ip
Data-Miner29 分钟前
需要做财务数据分析,有什么好用的工具?从准备到出报告的实操指南
大数据·数据库·数据分析
袋鼠云数栈1 小时前
让 SQL 解析不再重复造轮子:SqlParserX 正式开源
数据库·人工智能·sql·开源·数据治理
这个DBA有点耶1 小时前
期货 CTP 系统 Oracle RAC 迁移国产库实战:读写分离架构设计与性能对标
数据库·架构·dba
数据库安全2 小时前
AI数据访问安全 |如何控制AI访问权限,防止越权
数据库·安全
小羊没烦恼!2 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#
这个DBA有点耶2 小时前
Redo Log循环写与checkpoint推进:长事务阻塞下的Checkpoint风暴完整链路
数据库·mysql·代码规范
jnrjian3 小时前
pg_waldump --key-file-name status 查看wal 产生的db
数据库
SelectDB技术团队3 小时前
Snowflake 的开源替代怎么选:能力对照、三条部署路径与迁移执行
大数据·数据库·云原生·开源·snowflake·apache doris
Elastic 中国社区官方博客3 小时前
告别繁琐控制台:Kabanos 如何将 MongoDB Compass 的易用性带入 Elasticsearch
大数据·数据库·mongodb·elasticsearch·搜索引擎·全文检索