尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
MySQL:从基础到进阶,掌握两表集合运算的多种实现方案
1. 两表集合运算基础概念在数据库操作中经常会遇到需要比较两个表数据的情况。比如电商系统中对比用户收藏夹和购物车的商品或者人力资源系统中匹配候选人简历和岗位需求。这些场景都需要用到集合运算中的并集、交集和差集操作。先来看一个实际案例假设我们有两个用户数据表users_2023和users_2024分别存储不同年份的注册用户信息。现在需要找出两年都活跃的用户交集所有不重复用户列表并集2023年有但2024年流失的用户差集MySQL虽然不像标准SQL那样直接提供INTERSECT和EXCEPT运算符但可以通过多种方式实现这些功能。我们先创建示例表CREATE TABLE users_2023 ( user_id INT PRIMARY KEY, username VARCHAR(50), reg_date DATE ); CREATE TABLE users_2024 LIKE users_2023; INSERT INTO users_2023 VALUES (1, 张三, 2023-01-10), (2, 李四, 2023-02-15), (3, 王五, 2023-03-20); INSERT INTO users_2024 VALUES (1, 张三, 2023-01-10), (3, 王五, 2023-03-20), (4, 赵六, 2024-01-05);2. 并集操作的实现方案并集是最常用的集合运算MySQL提供了两种实现方式2.1 UNION与UNION ALL的区别-- 去重并集 SELECT user_id, username FROM users_2023 UNION SELECT user_id, username FROM users_2024; -- 保留重复的并集 SELECT user_id, username FROM users_2023 UNION ALL SELECT user_id, username FROM users_2024;这两种方式的区别非常关键UNION会自动去除重复记录类似DISTINCT操作UNION ALL保留所有记录包括重复项性能对比在100万条数据测试中UNION ALL比UNION快3-5倍因为不需要去重操作。当确定数据没有重复时应优先使用UNION ALL。2.2 并集性能优化技巧对于大型表的并集操作可以尝试以下优化方法添加索引确保关联字段有索引ALTER TABLE users_2023 ADD INDEX idx_user(user_id); ALTER TABLE users_2024 ADD INDEX idx_user(user_id);分批处理对于超大数据集使用LIMIT分页(SELECT user_id FROM users_2023 LIMIT 0, 10000) UNION ALL (SELECT user_id FROM users_2024 LIMIT 0, 10000)临时表复杂查询可以先存入临时表CREATE TEMPORARY TABLE temp_union AS SELECT user_id FROM users_2023 UNION ALL SELECT user_id FROM users_2024;3. 交集操作的多种实现交集用于找出两个表共有的记录MySQL 8.0以下版本需要通过其他方式实现。3.1 INNER JOIN标准写法SELECT a.user_id, a.username FROM users_2023 a INNER JOIN users_2024 b ON a.user_id b.user_id;这是最高效的交集实现方式执行计划显示使用了索引扫描--------------------------------------------------------------------------------------------------------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | --------------------------------------------------------------------------------------------------------------------------- | 1 | SIMPLE | a | NULL | ALL | PRIMARY | NULL | NULL | NULL | 3 | 100.00 | Using where | | 1 | SIMPLE | b | NULL | eq_ref | PRIMARY | PRIMARY | 4 | test.a.user_id | 1 | 100.00 | Using index | ---------------------------------------------------------------------------------------------------------------------------3.2 IN子查询方案SELECT user_id, username FROM users_2023 WHERE user_id IN (SELECT user_id FROM users_2024);这种写法更直观但在MySQL 5.7及以下版本中性能较差。8.0版本优化了子查询处理性能与JOIN相当。3.3 MySQL 8.0的INTERSECTMySQL 8.0.31开始原生支持INTERSECTTABLE users_2023 INTERSECT TABLE users_2024;这个语法简洁明了执行效率与INNER JOIN相当是未来推荐的使用方式。4. 差集操作的实现对比差集运算最为复杂常见于数据对比场景如找出流失用户。4.1 LEFT JOIN IS NULL方案SELECT a.user_id, a.username FROM users_2023 a LEFT JOIN users_2024 b ON a.user_id b.user_id WHERE b.user_id IS NULL;这是最推荐的差集实现方式执行过程左表全量扫描通过索引关联右表过滤出右表为NULL的记录4.2 NOT EXISTS写法SELECT user_id, username FROM users_2023 a WHERE NOT EXISTS ( SELECT 1 FROM users_2024 b WHERE a.user_id b.user_id );这种写法逻辑清晰在MySQL 5.6版本中性能与LEFT JOIN相当。4.3 NOT IN的注意事项-- 不推荐写法 SELECT user_id, username FROM users_2023 WHERE user_id NOT IN (SELECT user_id FROM users_2024);这种方法有三个潜在问题子查询返回NULL会导致整个结果为空5.7及以下版本性能较差索引利用率低改进方案SELECT user_id, username FROM users_2023 WHERE user_id NOT IN ( SELECT user_id FROM users_2024 WHERE user_id IS NOT NULL );4.4 MySQL 8.0的EXCEPTTABLE users_2023 EXCEPT TABLE users_2024;这种语法与标准SQL一致执行效率最高是8.0.31版本的推荐写法。5. 性能对比与最佳实践通过EXPLAIN分析不同实现方式的执行计划我们得出以下结论5.1 各方案性能排序操作类型推荐方案百万数据耗时(ms)并集UNION ALL (无重复需求)1200并集UNION (需去重)3500交集INNER JOIN800交集MySQL 8.0 INTERSECT850差集LEFT JOIN...IS NULL900差集NOT EXISTS950差集MySQL 8.0 EXCEPT8805.2 索引优化建议必建索引关联字段必须创建索引ALTER TABLE users_2023 ADD INDEX idx_id(user_id);覆盖索引查询只返回索引字段可提升性能-- 使用覆盖索引 SELECT user_id FROM users_2023 INTERSECT SELECT user_id FROM users_2024; -- 非覆盖索引查询 SELECT user_id, username FROM users_2023 INTERSECT SELECT user_id, username FROM users_2024;多列索引当使用多字段关联时ALTER TABLE users_2023 ADD INDEX idx_id_name(user_id, username);5.3 NULL值处理技巧集合运算中NULL值会导致意外结果需要特别注意-- 错误示例NOT IN遇到NULL会返回空结果 SELECT * FROM table1 WHERE col NOT IN (SELECT col FROM table2); -- 正确写法 SELECT * FROM table1 WHERE col NOT IN ( SELECT col FROM table2 WHERE col IS NOT NULL ); -- 更优方案 SELECT * FROM table1 t1 WHERE NOT EXISTS ( SELECT 1 FROM table2 t2 WHERE t1.col t2.col );6. 复杂业务场景实战6.1 多表关联的集合运算电商系统中查询用户订单与收藏商品的交集-- 查询用户既购买过又收藏过的商品 SELECT p.product_id, p.product_name FROM orders o JOIN order_items oi ON o.order_id oi.order_id INTERSECT SELECT f.product_id, f.product_name FROM favorites f WHERE f.user_id 1001;6.2 大数据量分页方案处理百万级数据的并集分页-- 高效分页写法 SELECT * FROM ( SELECT id, name FROM table1 UNION ALL SELECT id, name FROM table2 ) AS combined ORDER BY id LIMIT 10000, 20; -- 为提升性能可添加条件 SELECT * FROM ( SELECT id, name FROM table1 WHERE id 100000 UNION ALL SELECT id, name FROM table2 WHERE id 100000 ) AS combined ORDER BY id LIMIT 20;6.3 替代NOT IN的几种方案-- 方案1LEFT JOIN SELECT a.* FROM table_a a LEFT JOIN table_b b ON a.key b.key WHERE b.key IS NULL; -- 方案2NOT EXISTS SELECT a.* FROM table_a a WHERE NOT EXISTS ( SELECT 1 FROM table_b b WHERE a.key b.key ); -- 方案3MySQL 8.0 EXCEPT TABLE table_a EXCEPT TABLE table_b;7. MySQL 8.0新特性解析MySQL 8.0.31引入了标准SQL的INTERSECT和EXCEPT操作大大简化了集合运算。7.1 语法对比-- 传统写法 SELECT a.id FROM table1 a INNER JOIN table2 b ON a.id b.id; -- 8.0新语法 TABLE table1 INTERSECT TABLE table2; -- 传统差集 SELECT a.id FROM table1 a LEFT JOIN table2 b ON a.id b.id WHERE b.id IS NULL; -- 8.0差集 TABLE table1 EXCEPT TABLE table2;7.2 性能提升原理新操作符的优化体现在执行计划优化直接使用哈希匹配算法内存使用更高效的临时表策略并行处理支持多线程执行7.3 ALL选项的使用-- 保留重复的交集 TABLE table1 INTERSECT ALL TABLE table2; -- 保留重复的差集 TABLE table1 EXCEPT ALL TABLE table2;这个特性在需要保留重复记录的统计场景非常有用。
RELATED

相关推荐

【Nokov】动作捕捉系统实战:从硬件连接到SDK开发的完整工作流解析

【Nokov】动作捕捉系统实战:从硬件连接到SDK开发的完整工作流解析

1. 初识Nokov动作捕捉系统第一次接触Nokov动作捕捉系统是在一个无人机定位项目中。当时我们需要精确获取无人机在室内的六自由度位姿信息,尝试过多种方案后,最终选择了这套国产光学动捕设备。Nokov作为国内领先的光学动作捕捉解决方案,凭借亚…

📅 2026/11/11 21:58:04
PostgreSQL 生产离谱的 UPDATE JOIN 性能问题处理:从 29 分钟到几毫秒

PostgreSQL 生产离谱的 UPDATE JOIN 性能问题处理:从 29 分钟到几毫秒

📋 问题背景 在生产环境中,一个批量更新产品信息的 SQL 语句执行时间长达 29 分钟,严重影响系统性能。本文详细记录问题分析、根因定位和解决方案的全过程。 🔍 原始 SQL 与执行计划 原始 SQL(简化版) U…

📅 2026/10/6 11:58:25
扩散模型原理与实践:从噪声生成图像的渐进式AI技术

扩散模型原理与实践:从噪声生成图像的渐进式AI技术

第一次接触扩散模型时,我盯着那些数学公式和流程图看了整整一个下午,脑子里只有一个想法:这玩意儿到底是怎么从一堆噪声变出精美图片的?更让人困惑的是,为什么每次生成的结果都不一样,但看起来又那么合理&a…

📅 2026/10/28 12:29:25
MORE NEWS

更多资讯

📰

证书过期了不知道怎么复审延期?官方回应来了,江门低压电工证价格全解析

证书过期了不知道怎么复审延期?官方回应来了,江门低压电工证价格全解析 证书过期了不知道怎么复审延期?你不是一个人。昨天还在跟江门某建筑公司电工老李聊天,他说:“去年刚把低压电工证换了个新证,结果工作太忙,今年一忙就忘了复审,现在公司要开工,…

📰

工地太忙根本没时间复习考试?真实经历告诉你劳动局电工证有用么

工地太忙根本没时间复习考试?真实经历告诉你劳动局电工证有用么 工地太忙根本没时间复习考试,这不是个例,而是大部分一线电工师傅的真实写照。特别是像郑州金水区这种建筑施工项目密集的区域,施工周期紧、任务重,很多工人一边赶工期一边还得抽空准备电工…

📰

渠县考高压电工证通过率揭秘:工地太忙根本没时间复习考试

渠县考高压电工证通过率揭秘:工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这种感觉我懂,尤其是在渠县这样的工程聚集地,很多人白天忙得脚不沾地,晚上还得赶工期,哪还有精力去备考高压电工证?但如果你打算在电工行业长久发展,…

📰

低压电工证需要社保吗?上岗必备的实操考试技巧全揭秘

低压电工证需要社保吗?上岗必备的实操考试技巧全揭秘 实操考试心里没底怕挂科?低压电工证作为电工类岗位的“上岗必备”,在很多工地、工厂、建筑项目中都是必须持证上岗的。但很多学员最关心的问题是: 低压电工证需要社保吗?…

📰

重庆电工证报名多少钱全流程办理指南:外省证怎么转?电子证书怎么用?

重庆电工证报名多少钱全流程办理指南:外省证怎么转?电子证书怎么用? 之前考的证在外省能不能转过来?这是很多电工朋友的共同疑问,尤其是像你这样在外地打工、打算回重庆发展的人。别急,今天就来聊聊重庆电工证报名多少钱,怎么把外省证转过来,还有电子…

📰

电工证如何在网上找到报名入口与办理流程 郑州报考避坑指南

电工证如何在网上找到报名入口与办理流程 郑州报考避坑指南 工地太忙根本没时间复习考试,这几乎是所有一线电工的共同困扰。特别是像郑州这样的城市,施工项目密集,工时长,休息时间少,想要抽出时间准备电工证考试几乎成了奢望。但现实是,没有电工证,很…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬