Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

  • 多线程类

  • JVM 类

  • MySQL 类

    • MySQL 为什么一定要有一个主键
    • MySQL 中的 RR 隔离级别,到底有没有解决幻读问题
    • MySQL 的行级锁到底锁的是什么东西?
    • 存储 MD5 值应该用 VARCHAR 还是用 CHAR?
    • 数据库的三范式是什么?
    • 说说 InnoDB 与 MyISAM 的区别
    • drop、truncate、delete 的区别
    • 聊一聊数据库事务机制
    • 聊一聊 MySQL 中的关联查询
    • 事务隔离级别有哪些?MySQL 的默认隔离级别是什么
    • 分库分表之后,id 主键如何处理?
    • 说说在 MySQL 中一条查询 SQL 是如何执行的?
    • 讲解下 DDL、DML、DCL
    • 存储过程和触发器的作用
    • MySQL 如何行转列和列转行
    • 如何查看 SQL 的执行计划
    • union 和 unionAll 的区别
    • having 和 where 的区别
    • 常见的索引原则
    • MySQL 中的 IN 和 EXISTS 子句有什么区别?
      • MySQL 如何处理 NULL 值,对性能有什么影响?
      • 如何在 MySQL 中处理和避免全表扫描?
      • MySQL 中的表空间是什么,它的作用是什么?
      • 在 MySQL 中,如何优化 ORDER BY 查询?
    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • MySQL 类
    刘博
    2025-12-29
    目录

    MySQL 中的 IN 和 EXISTS 子句有什么区别?

    IN和EXISTS`均用于 “子查询条件判断”,核心区别在于 “查询逻辑” 和 “性能”,具体对比如下:

    # 1. 核心区别

    对比维度 IN EXISTS
    查询逻辑 先执行子查询,将结果集作为条件(如IN (1,2,3)),再执行主查询 先执行主查询,将主查询的每行数据传入子查询,判断子查询是否返回结果(存在则保留该行)
    子查询结果集 只能返回单列数据(如SELECT id FROM user) 可返回任意列(通常返回1,如SELECT 1 FROM order WHERE user_id = u.id)
    空值处理 子查询返回 NULL 时,IN条件恒为 FALSE(如WHERE id IN (NULL),无结果) 子查询返回 NULL 时,EXISTS条件恒为 FALSE
    性能差异 子查询结果集小时,性能优(内存中处理条件) 子查询结果集大时,性能优(主查询过滤后再执行子查询,减少子查询次数)
    适用场景 子查询结果集小(如 1000 行以内),主查询数据量大 子查询结果集大(如 10 万行以上),主查询数据量小

    # 2. 语法示例与执行逻辑

    # 测试数据:
    CREATE TABLE user (id INT PRIMARY KEY, name VARCHAR(20)); -- 主查询表(10万行)
    CREATE TABLE `order` (id INT PRIMARY KEY, user_id INT); -- 子查询表(100万行)
    
    1
    2
    # (1)IN 示例(子查询结果集小)

    需求:查询有订单的用户(子查询返回有订单的 user_id,结果集 1 万行)。

    SELECT * FROM user WHERE id IN (SELECT user_id FROM `order`);
    
    1
    # 执行逻辑:
    1. 先执行子查询SELECT user_id FROM order,返回 1 万行 user_id(如 1,2,3...);
    2. 主查询SELECT * FROM user WHERE id IN (1,2,3...),在 user 表中匹配 id,返回结果。
    # (2)EXISTS 示例(子查询结果集大)

    需求:查询有订单的用户(主查询先取 user 表的行,传入子查询判断)。

    SELECT * FROM user u WHERE EXISTS (SELECT 1 FROM `order` o WHERE o.user_id = u.id);
    
    1
    # 执行逻辑:
    1. 主查询取 user 表的第一行数据(u.id=1);
    2. 子查询SELECT 1 FROM order o WHERE o.user_id=1,判断是否有结果(有则返回 TRUE,无则返回 FALSE);
    3. 若子查询返回 TRUE,保留该行数据;否则丢弃;
    4. 主查询取 user 表的下一行数据,重复步骤 2-3,直到所有行处理完成。

    # 3. 性能优化建议

    • 子查询结果集小(<1 万行):优先使用 IN(子查询结果集加载到内存,主查询快速匹配);

    • 子查询结果集大(>10 万行):优先使用 EXISTS(主查询过滤后,子查询仅执行匹配的行,减少子查询次数);

    • 避免 IN 的子查询返回大量数据:若子查询返回 10 万行以上,IN 的条件会占用大量内存,性能下降,改为 EXISTS;

    • NOT IN 与 NOT EXISTS:NOT IN 性能极差(子查询返回 NULL 时结果不准确),优先使用 NOT EXISTS;

      -- 不推荐:NOT IN 性能差
      SELECT * FROM user WHERE id NOT IN (SELECT user_id FROM `order`);
      
      -- 推荐:NOT EXISTS 性能优
      SELECT * FROM user u WHERE NOT EXISTS (SELECT 1 FROM `order` o WHERE o.user_id = u.id);
      
      1
      2
      3
      4
      5

    上次更新: 12/30/2025
    常见的索引原则
    MySQL 如何处理 NULL 值,对性能有什么影响?

    ← 常见的索引原则 MySQL 如何处理 NULL 值,对性能有什么影响?→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式