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%左右,这绝对是非常实用的一个优化点!

相关推荐
笨小孩@GF 知行合一17 小时前
易语言-高级应用
数据库·编程·易语言·中文编程
KaiwuDB18 小时前
KaiwuDB 运维实战04:DRBD + KaiwuDB——物联网场景下的低成本数据库高可用方案
运维·数据库·物联网·时序数据库·kaiwudb·aiot·多模数据库
夜雪一千20 小时前
MySQL外键彻底入门:是什么、怎么用、什么时候不该用
数据库·mysql
qq_3344668620 小时前
删除SSMS的历史登录记录
数据库·sql
zl_dfq20 小时前
Redis 之 【常见面试题总结】(从数据类型到高可用、缓存一致性全解析)
数据库·redis
龙亘川20 小时前
铭记英烈守初心,数字强基促服务:亘川智城退役军人服务系统的实践与价值
java·数据库·人工智能
FYKJ_201021 小时前
SSM校园失物招领系统41452-计算机课程设计、毕业设计
java·vue.js·spring boot·python·mysql·typescript·spark
kv11021 小时前
Android studio国内开发有关
java·数据库·android studio
哭泣方源炼蛊1 天前
正则表达式c++内容汇集
数据库·c++·mysql·正则表达式