Oracle 中什么情况下 可以使用 EXISTS 替代 IN 提高查询效率

为什么 EXISTS 更高效?

EXISTS 提前终止:

     EXISTS 一旦在子查询中找到第一个匹配项,就会立即返回 TRUE,不再继续扫描子查询中的其他记录。
     IN 必须扫描整个子查询的结果集,将所有结果与主查询的每一行进行对比。

大数据集性能差异大:

     当子查询的数据集很大(如几万到几百万行)时,EXISTS 的提前终止特性会显著减少不必要的扫描。
     IN 在子查询中会生成临时结果集,这会导致更多的内存占用和性能开销。

🚀 EXISTS 替换 IN 的写法

IN 的原始写法:

SELECT * 
FROM employees e 
WHERE e.department_id IN ( 
    SELECT d.department_id 
    FROM departments d 
    WHERE d.department_name = 'SALES'
);

这段 SQL 查询的逻辑是,查询部门名为 ‘SALES’ 的所有员工。
这里的 IN 先生成一个临时结果集(d.department_id),并与 e.department_id 进行对比。

🔄 使用 EXISTS 替换 IN

SELECT * 
FROM employees e 
WHERE EXISTS ( 
    SELECT 1 
    FROM departments d 
    WHERE d.department_name = 'SALES' 
      AND d.department_id = e.department_id
);

这段 SQL 查询的逻辑是等价的。
不同点在于:

EXISTS 只要找到一个匹配项(d.department_id = e.department_id)就返回 TRUE,这时主查询中的这条 e 记录就被返回。
子查询中的 SELECT 1,实际上只要返回一行数据就能满足 EXISTS 条件,不需要返回字段值。

⚙️ EXISTS 和 IN 的区别

区别点INEXISTS
子查询结果生成子查询的完整结果集只要找到一个匹配的值就立即返回
子查询数据量适用于小数据集适用于大数据集
效率扫描整个子查询的结果集提前终止,效率高
关联条件主表的每一行与子查询的结果集比较子查询的条件与主表的每一行比较
内存使用子查询的结果集可能存储在临时表中不生成临时表,减少内存开销
索引利用索引不一定有效,可能全表扫描更容易利用索引

🔥 何时使用 EXISTS 替换 IN?

场景推荐使用方式原因
子查询返回大数据量EXISTS子查询中数据大,EXISTS 可以提前终止
子查询返回小数据量IN子查询小数据集,IN 性能也很好
子查询包含 NULL 值EXISTSIN 会因为 NULL 导致结果不匹配
主表数据多EXISTS主表数据多,EXISTS 在行对比上更高效
子查询不依赖主表IN如果子查询不依赖主表,IN 更清晰
子查询依赖主表EXISTS描子查询依赖主表的字段,EXISTS 更高效

🔍 示例 1:替代 IN 的常用场景

原始 SQL (使用 IN):

SELECT e.employee_name 
FROM employees e 
WHERE e.department_id IN (
    SELECT d.department_id 
    FROM departments d 
    WHERE d.department_name LIKE 'SALES%'
);

替换为 EXISTS:

SELECT e.employee_name 
FROM employees e 
WHERE EXISTS (
    SELECT 1 
    FROM departments d 
    WHERE d.department_name LIKE 'SALES%' 
      AND d.department_id = e.department_id
);

🔍 示例 2:避免 NULL 值的坑

原始 SQL (使用 IN):

SELECT * 
FROM employees e 
WHERE e.department_id IN (
    SELECT d.department_id 
    FROM departments d 
    WHERE d.department_name = 'SALES'
);

替换为 EXISTS:

SELECT * 
FROM employees e 
WHERE EXISTS (
    SELECT 1 
    FROM departments d 
    WHERE d.department_name = 'SALES' 
      AND d.department_id = e.department_id
);

🔍 示例 3:子查询依赖主表的场景

原始 SQL (使用 IN):

SELECT * 
FROM orders o 
WHERE o.customer_id IN (
    SELECT c.customer_id 
    FROM customers c 
    WHERE c.customer_type = o.customer_type
);

替换为 EXISTS:

SELECT * 
FROM orders o 
WHERE EXISTS (
    SELECT 1 
    FROM customers c 
    WHERE c.customer_type = o.customer_type 
      AND c.customer_id = o.customer_id
);

💡 总结

场景推荐使用
子查询返回大结果集EXISTS
子查询不依赖主表字段IN
子查询可能返回 NULLEXISTS
子查询依赖主表字段EXISTS
子查询小、主表大EXISTS
主表小、子查询大EXISTS

🚀 小结

  • EXISTS 在数据集较大时性能更高,尤其是子查询的返回数据量较大或包含 NULL 时。
  • EXISTS 避免了 IN 的“NULL 陷阱”,更安全。
  • 当子查询依赖主表的字段时,EXISTS 比 IN 更高效,因为不需要生成中间结果集。
  • EXISTS 可以提前终止子查询,在数据量较大时,性能优势更明显。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/940041.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【GCC】2015: draft-alvestrand-rmcat-congestion-03 机器翻译

腾讯云的一个分析,明显是看了这个论文和草案的 : 最新的是应该是这个 A Google Congestion Control Algorithm for Real-Time Communication draft-ietf-rmcat-gcc-02 下面的这个应该过期了: draft-alvestrand-rmcat-congestion-03

web自动化测试知识总结

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、自动化测试基本介绍 1、自动化测试概述: 什么是自动化测试?一般说来所有能替代人工测试的方式都属于自动化测试,即通过工…

进程间通信方式---消息队列(System V IPC)

进程间通信方式—消息队列(System V IPC) 文章目录 进程间通信方式---消息队列(System V IPC)消息队列1.消息队列进程间通信原理2.msgget 系统调用3.msgsnd 系统调用4.msgrcv 系统调用5.msgctl 系统调用6.函数使用案例7.实现生产者…

python学opencv|读取图像(十七)认识alpha通道

【1】引言 前序学习进程中,我们已经掌握了RGB和HSV图像的通道拆分和合并,获得了很多意想不到的效果,相关链接包括且不限于: python学opencv|读取图像(十二)BGR图像转HSV图像-CSDN博客 python学opencv|读…

Unity Post请求发送fromdata数据content-type

wwwfrom 的 headers["Content-Type"]修改 错误代码: WWWForm form new WWWForm(); if (form.headers.ContainsKey("Content-Type")) {string boundary string.Format("--{0}", DateTime.Now.Ticks.ToString("x"));form…

服务平滑发布与线上验证

发布策略可分为: 蓝绿发布:将新版本服务器全部发好后,将旧版本服务器的流量统一切换到新版本上灰度发布(金丝雀发布):是一种滚动发布方式,首先部署部分新版本服务器,将部分流量切到…

【数据安全】如何保证其安全

数据安全风险 数字经济时代,数据已成为重要的生产要素。智慧城市、智慧政务的建设,正以数据为核心,推动城市管理的智能化和公共服务的优化。然而,公共数据开放共享与隐私保护之间的矛盾日益凸显,如何在确保数据安全的…

ai论文生成器:分享8款AI一键生成论文的写作软件

在撰写毕业论文的过程中,高效利用各类软件工具可以极大地提升写作效率与质量。以下是八个免费的神器软件工具,它们各自在论文撰写、文献管理、语法校对、数据可视化等方面发挥着重要作用。希望这些推荐能帮助你顺利完成毕业论文的写作。 千笔AI论文&…

白话AI大模型(LLM)原理

大模型(例如 GPT-4或类似的深度学习模型)是基于神经网络的系统,用于理解、生成文本、图像或其他数据类型。其工作原理可以分为以下几个核心步骤,我将通过易于理解的例子逐一解释。 1. 神经网络的基本概念 大模型背后有一个非常庞…

数据压缩比 38.65%,TDengine 重塑 3H1 的存储与性能

小T导读:这篇文章是“2024,我想和 TDengine 谈谈”征文活动的三等奖作品之一。作者通过自身实践,详细分享了 TDengine 在高端装备运维服务平台中的应用,涵盖架构改造、性能测试、功能实现等多个方面。从压缩效率到查询性能&#x…

【Prometheus 】【实战篇(四)】Node Exporter安装方式(含一键安装脚本)及重要监控指标一览

目录 一、Node Exporter 1.8.2安装步骤详解1、下载 Node Exporter 安装包2、解压下载的文件3、将 Node Exporter 移动到 /usr/local/bin/4、创建一个专用的系统用户5、创建 systemd 服务文件6、重新加载 systemd 配置7、启动并启用 Node Exporter 服务8、检查 Node Exporter 状…

Qt之串口设计-线程实现(十二)

Qt开发 系列文章 - Serial-port(十二) 目录 前言 一、SerialPort 二、实现方式 1.创建类 2.相关功能函数 3.用户使用 4.效果演示 5.拓展应用-实时刷新 总结 前言 Qt作为一个跨平台的应用程序开发框架,在串口编程方面提供了方便易用…

信号处理相关的东东(学习解惑)

信号处理相关的东东(学习解惑) 所有内容学习自知乎专栏,https://www.zhihu.com/column/xinhao,写的很好,值得反复学习 时频域分析的一些常用概念 FROM:https://zhuanlan.zhihu.com/p/35742606 1、相加性…

使用 UniApp 在微信小程序中实现 SSE 流式响应

概述 服务端发送事件(Server-Sent Events, SSE)是一种允许服务器向客户端推送实时更新的技术。SSE 提供了一种单向的通信通道,服务器可以持续地向客户端发送数据,而不需要客户端频繁发起请求。这对于需要实时更新的应用场景非常有用。 流式传输的特点是将数据逐步传输给客…

【数据结构】八大排序

目录 一、直接插入排序 二、希尔排序 三、选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序 八、计数排序 稳定性结论 稳定性:排序后相同元素之间的相对顺序是否保持不变。 一、直接插入排序 基本思想:通过构建有序序列&#xff…

线程池ForkJoinPool详解

由一道算法题引发的思考 算法题:如何充分利用多核CPU的性能,快速对一个2千万大小的数组进行排序? 这道算法题可以拆解来看: 1)首先这是一道排序的算法题,而且是需要使用高效的排序算法对2千万大小的数组…

python08-序列02-字典dict、集合set

一、字典(dict):可变数据类型 1-1、字典的特点 字典是可变数据类型(list也是),具有增、删、改等一系列的操作;字典中的元素是无序的(hash)key必须唯一,value…

【Java项目】基于SpringBoot的【旅游管理系统 】

【Java项目】基于SpringBoot的【旅游管理系统 】 技术简介:本系统使用JAVA语言开发,采用B/S架构、Spring Boot框架、MYSQL数据库进行开发设计。 系统简介:(1)管理员功能:可以管理个人中心、用户管理、景区分…

UE5 跟踪能力的简单小怪

A、思路 1、用素材的骨骼网格体创建小怪BP,绑定新的小怪控制器。 2、控制器的事件开始时,获取玩家状态,指定AI小怪自动向玩家移动。 复杂的AI需要用强大功能如黑板、行为树。 而简单的AI则可以用简单方法实现,杀鸡不用牛刀。视…

渗透测试学习笔记(五)网络

一.IP地址 1. IP地址详解 ip地址是唯一标识,一段网络编码局域网(内网):交换机-网线-pcx.x.x.x 32位置2进制(0-255) IP地址五大类 IP类型IP范围A类0.0.0.0 到 127.255.255.255B类128.0.0.0 到191.255.25…