sql优化:使用 exists 优化 in () 或 = ()

1、使用 exists 优化 in ()

优化前:

select
id, order_no, apply_time, apply_dept, apply_operator, purpose, stage, remark
from BranchWarehouseApplyMaster
where stage = 0 and warehouse_id = 1
and apply_dept in (
select emp_DeptID
from Employee
where emp_ID = 'manager'
)

优化后:

select
id, order_no, apply_time, apply_dept, apply_operator, purpose, stage, remark
from BranchWarehouseApplyMaster
where stage = 0 and warehouse_id = 1
and exists (
select 1
from Employee
where emp_ID = 'manager'
and emp_DeptID = apply_dept
)

2、使用 exists 优化 in ()

优化前:

select
id, order_no, apply_time, apply_dept, apply_operator, purpose, stage, remark
from BranchWarehouseApplyMaster
where stage = 0 and warehouse_id = 1
and apply_dept = (
select top 1 emp_DeptID
from Employee
where emp_ID = 'manager'
)

 优化后:

select
id, order_no, apply_time, apply_dept, apply_operator, purpose, stage, remark
from BranchWarehouseApplyMaster
where stage = 0 and warehouse_id = 1
and exists (
select 1
from Employee
where emp_ID = 'manager'
and emp_DeptID = apply_dept
)

3、最终优化建议

优化前:

select
id, order_no, apply_time, apply_dept, apply_operator, purpose, stage, remark
from BranchWarehouseApplyMaster
where stage = 0 and warehouse_id = 1
and exists (
select 1
from Employee
where emp_ID = 'manager'
and emp_DeptID = apply_dept
)

优化说明:

  1. 索引优化(关键步骤):

    • 主表索引:为BranchWarehouseApplyMaster创建复合索引:

      sql

      复制

      下载

      CREATE INDEX master_idx ON BranchWarehouseApplyMaster(stage, warehouse_id, apply_dept);

      该索引直接覆盖WHERE条件(stagewarehouse_id作为最左前缀)和连接字段apply_dept,避免全表扫描。

    • 子查询表索引:为Employee创建覆盖索引:

      sql

      复制

      下载

      CREATE INDEX emp_idx ON Employee(emp_ID, emp_DeptID);

      该索引直接覆盖子查询条件(emp_ID = 'manager')和返回字段emp_DeptID,大幅提升子查询效率。

  2. 重写EXISTS为IN

    • EXISTS子查询逐行检查,效率较低。改为IN子查询后:

      • 子查询先执行,结果(部门ID列表)被缓存。

      • 主表通过apply_dept IN (...) + 复合索引快速定位记录。

    • 实际测试中,多数数据库(如MySQL)对IN的优化优于EXISTS,尤其当子查询结果集较小时。

  3. 执行计划提示(可选):

    • /*+ USE_INDEX(master_idx) */ 强制使用创建的复合索引,避免优化器误选低效索引。

备选方案(JOIN写法):

sql

复制

下载

SELECT m.id, m.order_no, m.apply_time, m.apply_dept, m.apply_operator, m.purpose, m.stage, m.remark
FROM BranchWarehouseApplyMaster m
JOIN (SELECT DISTINCT emp_DeptID FROM Employee WHERE emp_ID = 'manager'
) e ON m.apply_dept = e.emp_DeptID  -- 预过滤部门列表
WHERE m.stage = 0 AND m.warehouse_id = 1;

优点:子查询仅执行一次,通过DISTINCT去重后连接,避免重复扫描。

优化效果:

  • 索引生效:主表通过复合索引快速过滤stage=0 + warehouse_id=1的记录,再通过apply_dept匹配部门列表。

  • 子查询优化Employee表通过索引直接定位manager的部门,无需全表扫描。

  • 数据流减少:IN或JOIN写法将逐行校验改为集合匹配,减少数据库内部循环操作。

注意:实际执行前需在测试环境验证执行计划,确保索引被正确使用。如果manager对应的部门极少,IN/JOIN方案更优;如果部门较多,可考虑恢复EXISTS但确保索引有效。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTTP 响应状态码

HTTP 响应状态码(Response Status Codes) HTTP 响应状态码用于表示服务器对客户端请求的处理结果,由3位数字 组成,分为5类: 状态码 类别 常见状态码 说明 1xx 信息响应 100(Continue) …

如何通过插件系统打造个性化效率工作流

在现代工作流中,快速调用工具与自动化操作已成为提升生产力的核心环节。一款真正出色的效率工具,不仅要在响应速度和跨平台兼容性上表现出色,更需要具备高度的可扩展性,以满足多样化的使用场景。 它不仅轻量高效,还支…

Spring上下文模块设计

经过此前我们设计的如:IoC、Web、数据访问、AOP等模块的设计,我们从设计上已经搭建好了Spring的基础骨架了,但聪明的码友会思考想到:作为一个基础框架而言,目前应该是已经够用了的,但是上进的码友怎么会就此…

keil5怎么关闭工程

在project里面有一个close project,点击后就关掉了,之前还按照其他软件的操作习惯,右键工程选项,但是始终没有发现关闭选项。

腾讯云:6月30日起,自动禁用,及时排查

大家好,我是小悟。 腾讯云发布公告,宣布从2025年6月30日开始,对长期未使用的AccessKey(API访问密钥)进行自动禁用。 简单来说,如果你的密钥在90天内没动静,系统就会把它关掉,不管是…

【C++】多重继承与虚继承

多重继承与虚继承 1.单继承和多重继承的区别2.语法规则示例代码:多重继承子类指定父类的构造示例代码:多重继承子类隐藏父类的同名方法 3.虚继承解决多重继承遇到的bug示例代码:环状继承引发的问题 3.1 虚基类:3.2 语法规则&#…

GCC编译/连接/优化等选项

1. GCC编译/连接/优化等选项 1. GCC编译/连接/优化等选项 1.1. 简介1.2. 常用选项 1.2.1. -c -E -S -o1.2.2. -L<path> -l<library>1.2.3. -D<macro>1.2.4. -I<path> 1.3. 代码生成和优化 1.3.1. -std<standard>1.3.2. -shared1.3.3. -fPIC1.3.…

FFmpeg 压缩视频文件

文章目录 FFmpeg 压缩视频文件基本压缩命令&#xff08;保持 MP4 格式&#xff09;转换为其他格式示例&#xff1a;关键参数说明&#xff1a;额外优化选项&#xff1a; 在FFmpeg中使用多线程加速1. 帧级多线程 (frame-level multithreading)2. 切片级多线程 (slice-level multi…

Ubuntu 系统通过防火墙管控 Docker 容器

Ubuntu 系统通过防火墙管控 Docker 容器指南 一、基础防火墙配置 # 启用防火墙 sudo ufw enable# 允许 SSH 连接&#xff08;防止配置过程中断联&#xff09; sudo ufw allow 22/tcp二、Docker 配置调整 # 编辑 Docker 配置文件 sudo vim /etc/docker/daemon.json配置文件内…

虚拟机新增硬盘,与数据挂载

我有个虚拟机&#xff0c;当时选择了独立文件&#xff0c;现在遇到个问题&#xff0c;硬盘不够了&#xff0c;索性加了一个新硬盘&#xff0c;现在想把数据库的数据映射到这个新的硬盘处理。 罗列硬盘 lsblk我得是sdb是新硬盘 2. 分区 sudo fdisk /dev/sdb交互操作&#xff…

go语言学习 第10章:面向对象编程

第10章&#xff1a;面向对象编程 面向对象编程&#xff08;OOP&#xff09;是一种编程范式&#xff0c;它使用“对象”来表示数据和方法&#xff0c;并通过类来定义对象的结构和行为。Go语言虽然不是传统的面向对象语言&#xff0c;但它通过结构体&#xff08;struct&#xff…

android计算器代码

本次作业要求实现一个计算器应用的基础框架。以下是布局文件的核心代码&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"andr…

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…

我们来学mysql -- 8.4版本记录慢查询

记录慢查询 开启慢查询的配置查看慢查询状态动态开启慢查询日志永久开启配置log_throttle_queries_not_using_indexes 记录慢查询对性能的影响实际案例说明第一条记录第二条记录第三条记录第四条记录 开启慢查询的配置 查看慢查询状态 - 执行 show variables like slow_quer…

2025 年中国大学生程序设计竞赛全国邀请赛(郑州)暨第七届CCPC河南省大学生程序设计竞赛(补题)

文章目录 前言F、幻形之路G、直径与最大独立集H&#xff0c;树论函数M&#xff0c; 川陀航空学院总结 前言 本次比赛&#xff0c;只能说太多没接触的知识了&#xff0c;还有太容易被题面吓住。 F、幻形之路 题目链接&#xff1a;幻形之路 解题思路&#xff1a; 对于这一题只…

如何使用k8s安装redis呢

在Kubernetes (k8s) 上安装Redis 在Kubernetes上安装Redis有几种方法&#xff0c;下面我将介绍两种常见的方式&#xff1a;使用StatefulSet直接部署和使用Helm chart部署。 一、安装redis 1.1 拉去ARM镜像&#xff08;7.4.2&#xff09; docker pull registry.cn-hangzhou.ali…

SpringBoot的5种日志输出规范策略

在企业级应用开发中&#xff0c;合理规范的日志记录是系统稳定运行、问题排查和性能优化的关键保障。 SpringBoot作为流行的Java开发框架&#xff0c;提供了强大而灵活的日志支持&#xff0c;但如何建立统一、高效的日志输出规范却是许多团队面临的挑战。 本文将介绍SpringBo…

Python Cookbook-7.11 在 PostgreSQL 中储存 BLOB

任务 需要将 BLOB 存入一个 PostgreSQL 数据库。 解决方案 PostgreSQL7.2 以及更新的版本支持大对象,而psycopg 模块提供了二进制转义函数: import psycopg,cPickle #连接到数据库,用你的本机来测试数据库,并获得游标 connection = psycopg.connect("dbname = test…

Android端口转发

如上图所示&#xff0c;有一个Android设备&#xff0c;Android设备里面有主板&#xff0c;主板上有网络接口和Wi-Fi&#xff0c;网络接口通过网线连接了一个网络摄像头&#xff0c;这就跟电脑一样&#xff0c;电脑即可以通过网线接入一个网络&#xff0c;也可以同时用Wi-Fi接入…

Unity基础-协程

Unity基础-协程 四、协程 概述 协程&#xff08;Coroutine&#xff09;&#xff0c;本质上并不是多线程&#xff0c;而是在当前线程中将代码分时执行&#xff0c;不卡主线程。可以理解为&#xff0c;协程会把可能使主线程卡顿的程序分时分布进行。 协程通常用来&#xff1a;…