SQL 深度精讲|IN 与 NOT IN 用法、底层原理、NULL 致命坑、性能优化(实战干货)

摘要:IN / NOT IN 是 SQL 开发中高频使用的多条件筛选语法,可高效替代多段 OR 语句。但多数开发者仅掌握基础用法,忽略 NOT IN 针对 NULL 值的逻辑缺陷、大数据量索引失效、慢查询隐患等生产级问题。本文从基础语法、实战案例、底层逻辑、高危坑点、性能优化、生产替代方案全方位讲解,适配 MySQL 主流数据库,所有代码可直接落地运行,适合开发自查与面试复盘。

关键词:SQL;MySQL;IN;NOT IN;SQL优化;数据库索引;SQL避坑;慢查询优化

一、前言

在日常业务开发、数据统计、报表查询中,多值条件筛选是刚需场景。如果长期使用 OR 拼接多条件,不仅代码冗余、可读性差,还极易出现语法错误。

此时 IN 和 NOT IN 就是最优解。

但在生产环境中,很多 数据统计异常、查询结果为空、慢查询拖库 问题,根源均来自 NOT IN 的隐性逻辑漏洞和不当使用。

本文结合实战场景,完整梳理 IN / NOT IN 全套知识点,重点解决生产踩坑与性能优化问题。

二、IN / NOT IN 核心定义与基础语法

2.1 核心语义

  • IN:匹配字段值存在于指定列表中的数据,属于包含查询
  • NOT IN:匹配字段值不存在于指定列表中的数据,属于排除查询

2.2 通用标准语法

适配 MySQL、Oracle、SQL Server 全系列数据库:

IN 语法

|------------------------------------------------------------------------------------------|
| sql SELECT column1, column2 FROM table_name WHERE column IN (value1, value2, value3...); |

NOT IN 语法

|----------------------------------------------------------------------------------------------|
| sql SELECT column1, column2 FROM table_name WHERE column NOT IN (value1, value2, value3...); |

三、基础实战案例(可直接运行)

基于业务常用 user 用户表演示基础筛选场景,对比传统 OR 写法与 IN 写法的优劣。

3.1 IN 实战:批量多值匹配

需求:查询年龄为 18、20、25 的所有用户

|-----------------------------------------------------------------------------|
| sql -- 简洁高效写法(推荐) SELECT id, name, age FROM user WHERE age IN (18, 20, 25); |

等价 OR 冗余写法(不推荐):

|----------------------------------------------------------------------------|
| sql SELECT id, name, age FROM user WHERE age = 18 OR age = 20 OR age = 25; |

值越多,IN 语法的简洁性和可维护性优势越明显。

3.2 NOT IN 实战:批量排除匹配

需求:查询年龄非 18、20、25 的所有用户

|-------------------------------------------------------------------|
| sql SELECT id, name, age FROM user WHERE age NOT IN (18, 20, 25); |

四、进阶用法:子查询动态筛选(生产高频)

真实开发中极少使用固定值列表,更多通过 子查询动态关联数据,实现跨表筛选。

涉及两张业务表:

  • student:学生信息表
  • score:学生成绩表,关联字段 student_id

4.1 IN 子查询:查询有成绩的学生

|------------------------------------------------------------------------------|
| sql SELECT id, name FROM student WHERE id IN (SELECT student_id FROM score); |

4.2 NOT IN 子查询:查询无成绩的学生(高危场景)

|-----------------------------------------------------------------------------------------------------|
| sql -- 存在严重生产隐患!禁止直接使用 SELECT id, name FROM student WHERE id NOT IN (SELECT student_id FROM score); |

重点:该写法是新手及初级开发高频翻车点,下文详细解析坑点与解决方案

五、生产致命坑:NOT IN + NULL 空值陷阱

5.1 故障现象

当 NOT IN 后的子查询结果中 存在 NULL 值 ,整条 SQL 查询结果会 直接返回空数据,无报错、无异常,极难排查。

5.2 底层原理

SQL 三值逻辑:True / False / Unknown。

任何值与 NULL 进行比对,结果均为 Unknown,NOT IN 无法匹配未知状态,所有数据都会被判定为不匹配,最终结果集为空。

5.3 标准修复方案

子查询中强制过滤 NULL 值,从根源规避问题:

|---------------------------------------------------------------------------------------------------------------------------|
| sql -- 生产安全写法 SELECT id, name FROM student WHERE id NOT IN ( SELECT student_id FROM score WHERE student_id IS NOT NULL ); |

生产规范:所有 NOT IN 子查询,必须增加 IS NOT NULL 过滤条件

六、IN / NOT IN 性能深度优化

6.1 适用场景划分

  • 小数据量、固定少量值:优先使用 IN / NOT IN,语法简洁、可读性高
  • 大数据量、子查询结果集庞大:IN 容易触发索引失效、全表扫描,引发慢查询

6.2 生产最优替代方案

针对大数据量、高并发业务,禁止使用 NOT IN ,统一使用 NOT EXISTS

|----------------------------------------------------------------------------------------------------------------------------------------------|
| sql -- 大数据量高性能写法,无NULL坑、命中索引、效率更高 SELECT s.id, s.name FROM student s WHERE NOT EXISTS ( SELECT 1 FROM score sc WHERE sc.student_id = s.id ); |

6.3 核心性能对比

  • NOT IN:存在 NULL 逻辑坑、大数据量索引失效、全表比对效率低
  • NOT EXISTS:基于索引匹配、无空值逻辑缺陷、遍历效率更高,生产首选

七、核心知识点总结

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| plain text 【SQL IN / NOT IN 生产级总结】 1. IN 用于多值包含查询,完美替代批量 OR 语句,代码简洁易维护 2. NOT IN 用于多值排除查询,存在致命 NULL 空值陷阱 3. NOT IN 子查询包含 NULL 时,结果集直接为空,无报错难以排查 4. 开发规范:NOT IN 子查询必须携带 IS NOT NULL 过滤 5. 小数据量场景:优先使用 IN / NOT IN 6. 大数据量、高并发场景:统一使用 EXISTS / NOT EXISTS 替代 7. IN 列表值过多会触发索引失效,需控制参数数量 |

八、写在最后

IN 和 NOT IN 看似是 SQL 基础语法,实则包含大量生产细节与底层逻辑。很多线上数据异常、慢查询问题,均是开发者忽视空值逻辑、性能特性导致。

掌握 基础用法 + 空值避坑 + 性能优化 + 生产替代方案,才能真正适配企业级开发规范,写出健壮、高效、零BUG 的 SQL 语句。

欢迎点赞、收藏、关注,持续更新 Java / SQL / 数据库优化、后端实战干货!

#SQL #MySQL #数据库 #SQL优化 #后端开发 #编程干货 #数据库避坑 #慢查询优化

相关推荐
隔振消音专家1 小时前
冷水机组振动传导影响及专业化减振适配治理方案
大数据·运维
大公产经晚间消息1 小时前
“胜算未来·2026戈峻思享会”即将登陆大连
大数据·人工智能·ai
IvorySQL1 小时前
PG 日报|修复高 IO 并发场景,解决预读机制耗尽本地缓冲区缺陷
数据库·人工智能·sql·postgresql·区块链
TiDB 社区干货传送门1 小时前
TiDB 8.5.7 发版|六项实用功能上线
数据库·mysql·tidb
清泓y1 小时前
Android内存管理与性能优化面试真题
android·面试·性能优化
在繁华处1 小时前
MySQL 学习笔记 01:从概念到约束,搭好库表骨架
数据库·oracle
Y3815326622 小时前
3 种 SERP 数据处理方案对比:流式 / 批处理 / 缓存
java·spring·缓存
huihui3612 小时前
北京比较好的商会私域管理软件推荐:选型标准与核验要点
大数据
三言老师2 小时前
CentOS7.9:Redis 数据持久化结构化实战教程
数据库·redis·缓存
数智顾问2 小时前
(84页PPT)PWC海科集团生物医药业务5年发展战略项目建议书(附下载方式)
大数据·人工智能·物联网