LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

SQL查询速度慢?舍弃''in''和''not in'',让你的数据库飞起来

admin
2025年4月9日 14:47 本文热度 95

引言

最近在重构一个老项目时,被一段SQL查询卡得死死的,排查下来才发现是 IN 和 NOT IN 惹的祸。虽然这两个关键字看着挺顺手,写起来也方便,但我今天就来说说为啥真正的开发老司机都悄悄抛弃了它们。

性能差到惊人:一个血的教训

前段时间我在处理用户数据同步时遇到个情况:users表和user_profiles表都是90万条数据左右,大概300MB,完全算不上大表。结果我随手写了句:

SELECT * FROM users WHERE mobile NOT IN (SELECT mobile FROM user_profiles)

这条查询直接把我整懵了...跑了几分钟还没出结果!检查后发现mobile字段在两个表都建了索引,类型也完全一致。执行explain后才知道,原来NOT IN这种操作方式没走索引,难怪这么慢。改成了EXISTS后,整个世界都清静了:

SELECT * FROM users 
WHERE NOT EXISTS (SELECT mobile FROM user_profiles WHERE users.mobile = user_profiles.mobile)

仅仅十几秒就跑完了,简直天壤地别!

最坑的是:它不会明确报错,让你吃暗亏

除了慢,IN/NOT IN还有个更恶心的问题:容易写错但不会报错,查出来的结果还看着像那么回事。我用两个简单的表来演示:

CREATE TABLE employees (emp_id INT);
CREATE TABLE departments (dept_id INT);

INSERT INTO employees (emp_id) VALUES (1),(2),(3);
INSERT INTO departments (dept_id) VALUES (1),(2);

如果我想找出在departments表中存在的员工ID,正常应该这么写:

SELECT emp_id FROM employees
WHERE emp_id IN (SELECT dept_id FROM departments)

结果很正常:返回1和2。但假如我手抖写成了:

SELECT emp_id FROM employees 
WHERE emp_id IN (SELECT emp_id FROM departments)

注意看,我把子查询里的dept_id写成了emp_id。魔幻的是,这句SQL居然不报错!直接返回了1、2、3所有数据!更扯的是,如果单独执行SELECT emp_id FROM departments肯定会报错"列名'emp_id'无效",但放在IN子查询里就不报错了,这也太阴险了吧。

老司机都用啥替代方案?

既然IN和NOT IN这么不靠谱,咱们就用更稳的方案:

方案一:EXISTS/NOT EXISTS

-- 代替IN
SELECT * FROM employees
WHERE EXISTS (SELECT 1 FROM departments WHERE departments.dept_id = employees.emp_id);

-- 代替NOT IN
SELECT * FROM employees
WHERE NOT EXISTS (SELECT 1 FROM departments WHERE departments.dept_id = employees.emp_id);

方案二:JOIN大法

-- 代替IN
SELECT employees.emp_id FROM employees
INNER JOIN departments ON departments.dept_id = employees.emp_id;

-- 代替NOT IN
SELECT employees.emp_id FROM employees
LEFT JOIN departments ON departments.dept_id = employees.emp_id
WHERE departments.dept_id IS NULL;

这两种方法不仅性能好,而且对NULL的处理也更加合理,不会搞出莫名其妙的结果。

说真的,少用IN和NOT IN吧

看完这些例子,我是再也不敢随便用IN和NOT IN了。虽然它们看起来简单直观,写起来也省事,但隐藏的坑实在太多。特别是在处理大量数据的时候,性能差异简直就是天壤之别。如果你们团队的代码库里还有这种写法,赶紧改掉吧!别等到生产环境出了问题才来查原因。


该文章在 2025/4/11 10:15:48 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved