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优化 #后端开发 #编程干货 #数据库避坑 #慢查询优化

相关推荐
润乾软件3 小时前
SQLazy:分组累计求和
sql·sqlazy
小江的记录本4 小时前
【CSS】CSS 动画:transition、animation、transform、CSS3 新特性(附《思维导图》)
前端·css·安全·spring·前端框架·css3·动画
爱喝水的鱼丶4 小时前
SAP-ABAP:SAP学习分享:深入理解事务码ME32K——更改采购合同
性能优化·sap·abap·业务学习·开发交流·交流学习·采购合同
宸津-代码粉碎机4 小时前
AI攻防战升级!基于Spring AI构建Java应用自动免疫安全体系
java·大数据·开发语言·人工智能·python·安全·spring
倔强的石头_4 小时前
连接数失控排查:从数据库会话、应用线程池到连接池泄漏
数据库
爱喝水的鱼丶5 小时前
SAP-ABAP:ABAP 用户出口开发规范与避坑指南:10 类典型错误与运维方案
运维·性能优化·sap·abap·增强·经验交流·出口
hzxpaipai5 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构
博、、5 小时前
从零构建智慧场馆解决方案:架构设计与开发实践
大数据·运维
AI行业说5 小时前
誉财自动化YC-18-M8045实测:服装自动化vs人工缝制产能成本对比
大数据·人工智能·自动化·智能模板机
2601_963749105 小时前
越华环保集团数字化污水治理:端边云采集架构与平台对接实现
java·大数据·架构