当 SQL 卡住时,你是不是这样?
“为啥查询跑了 10 分钟还没结果?”
“NOT IN 子查询又把数据库搞崩溃了!”
别慌!今天教你用LEFT JOIN+IS NULL组合拳,让查询效率原地起飞~
实战场景:找 “失踪人口”
假设你有两个表:
tableA(目标表)
Key | Value |
A1 | 100 |
A2 | 200 |
A3 | 300 |
tableB(对比表)
Key | Value |
A2 | 250 |
A4 | 400 |
需求:查出 tableA 中在 tableB 里不存在的记录
传统写法:NOT IN 和 NOT EXISTS 有多拉垮?
-- NOT IN:子查询像“复读机”,每条数据都要查一遍
SELECT * FROM tableA A WHERE A.Key NOT IN (SELECT B.Key FROM tableB B);
-- NOT EXISTS:更像“碎碎念”,逐条对比累到吐血
SELECT * FROM tableA A WHERE NOT EXISTS (SELECT 1 FROM tableB B WHERE B.Key = A.Key);
问题本质: 数据量大时,子查询会被反复执行,数据库直接 “累瘫”,查询速度比蜗牛爬还慢!
高效解法:LEFT JOIN 秒变 “效率王者”
-- LEFT JOIN+IS NULL:一步到位的神仙操作
SELECT A.* FROM tableA A
LEFT JOIN tableB B ON A.Key = B.Key
WHERE B.Key IS NULL;
白话解析:
- LEFT JOIN像 “牵红线的红娘”,把 tableA 和 tableB 按 Key 字段 “相亲”;
- 没 “配对成功” 的记录(即 tableB 中不存在的 Key),会在 B.Key 字段留下NULL;
- 用WHERE B.Key IS NULL筛选出这些 “单身狗” 记录,就是 tableA 独有的数据!
为什么 LEFT JOIN 快到飞起?
对比项 | NOT IN/NOT EXISTS | LEFT JOIN+IS NULL |
执行逻辑 | 子查询反复查,相当于 “盲搜” | 一次 JOIN 完成关联,相当于 “精准定位” |
索引利用 | 难走索引,效率低下 | 可充分利用索引,速度飙升 |
大数据表现 | 数据越多越卡,甚至崩溃 | 数据量越大,优势越明显 |
类比场景:
找一本绝版书时:
- NOT IN 像在图书馆里闭着眼睛乱摸,全靠运气;
- LEFT JOIN 像提前知道书在 “3 楼 C 区 5 排”,直接冲过去拿!
终极口诀:下次直接套公式
当需要 “查 A 表不在 B 表的数据” 时,直接复制以下代码:
SELECT A.* FROM 表A A
LEFT JOIN 表B B ON A.关联字段 = B.关联字段
WHERE B.关联字段 IS NULL;
同事看到后的反应:
“你这 SQL 写得也太秀了吧!查询怎么突然快了 10 倍?”
额外福利:性能测试小技巧
想验证效果?试试用EXPLAIN关键字:
EXPLAIN SELECT * FROM tableA A WHERE A.Key NOT IN (...);
EXPLAIN SELECT A.* FROM tableA A LEFT JOIN tableB B ON...;
对比执行计划,你会看到 LEFT JOIN 的 “成本值” 低到感人!
最后提醒: 记得把这篇文章收藏 + 转发,下次写 SQL 再也不怕被 DBA 怼 “查询太慢” 啦~