SQL 中为什么参数多了not in 比 in 慢多了,怎么优化

开发工作中,我发现一个现象,比喻下面的两个语句:

select * from shangpin where spdm in ('1','2','3',...);
select * from shangpin where spdm not in ('1','2','3',...);

当参数比较少的时候还看不出来什么,但是遇到参数上了几百几千,那么 in 受的影响不大,not in 查询的结果就超级慢了。

那么什么原因导致NOT IN 可能比 IN 慢很多呢?

1. 逻辑复杂度不同

  • IN 子句:用于检查一个值是否存在于一组特定的值中。对于数据库引擎来说,这是一个相对直接的操作,因为它只需要找到匹配项即可。
  • NOT IN 子句:则需要确保目标值不在给定的集合中。这意味着对于每一个值,数据库必须确认它不等于列表中的任何一项,这通常涉及更多的比较操作。

2. NULL值的影响

  • 如果NOT IN子句中的任意一个值是NULL,整个查询结果将返回空(因为任何与NULL的比较都是未知)。为了处理这种情况,数据库系统可能需要额外的逻辑来确保正确性,从而增加了计算成本。
  • 相反,IN子句可以更高效地处理NULL值,因为它只需查找是否存在匹配项。

3. 索引使用效率

  • 在某些情况下,数据库优化器可能无法有效地利用索引来加速NOT IN查询,尤其是当子查询或列表非常大时。相比之下,IN子句通常更容易被优化器识别为可以使用索引的情况,从而提高执行速度。

4. 查询转换

  • 数据库系统有时会将NOT IN重写为其他形式的查询(例如使用LEFT JOIN加上WHERE条件过滤掉匹配行),这种转换可能会导致更低的执行效率,尤其是在大数据集上。
  • 而IN子句通常不需要这样的重写,可以直接应用于索引或其他优化策略。

5. 数据量的影响

  • 当IN子句包含大量值时,虽然性能也会受到影响,但大多数现代数据库管理系统都针对这种情况进行了优化。然而,随着NOT IN列表的增长,由于其内在的逻辑复杂性和潜在的全表扫描需求,性能下降的速度往往更快。

那么怎么去优化?

我的方法是这样:

StringBuffer notexistsSqlBuffer=new StringBuffer();
            if (spdmListLw.size() > 0) {
                notexistsSqlBuffer.append("SELECT 1 \n");
                notexistsSqlBuffer.append("FROM (\n");
                notexistsSqlBuffer.append("SELECT spdm FROM (\n");
                notexistsSqlBuffer.append("VALUES\n");
                for (int i = 0; i < spdmListLw.size(); i++) {
                    if(i!=0) notexistsSqlBuffer.append(",");
                    notexistsSqlBuffer.append("('"+spdmListLw.get(i)+"')");
                }
                notexistsSqlBuffer.append(") AS spdm_list(spdm)\n");
                notexistsSqlBuffer.append(") AS excluded_spdm\n");
                notexistsSqlBuffer.append("WHERE excluded_spdm.spdm =shangpin.spdm");
}

wrapper.notExists( spdmListLw.size() > 0,notexistsSqlBuffer.toString())

拼成的结果大致是这样:

select * from shangpin where not exists (
		select 1 from (
				SELECT spdm FROM ( VALUES ('1'),('2'),('1'),...) AS spdm_list(spdm)
		)	AS excluded_spdm	
    WHERE excluded_spdm.spdm =shangpin.spdm
)


MySQL 8.0及以上版本才支持支持VALUES行构造器),可以使用uion all 替代

      StringBuffer notexistsSqlBuffer=new StringBuffer();
            if (spdmListLw.size() > 0) {
                notexistsSqlBuffer.append("SELECT 1 FROM (\n");
                for (int i = 0; i < spdmListLw.size(); i++) {
                    if(i!=0) notexistsSqlBuffer.append(" UNION ALL ");
                    notexistsSqlBuffer.append(" SELECT '"+spdmListLw.get(i)+"' ");
                    if(i==0) notexistsSqlBuffer.append(" AS SPDM ");
                }
                notexistsSqlBuffer.append(" ) as excluded_spdm \n");
                notexistsSqlBuffer.append("WHERE excluded_spdm.spdm =com_base_shangpin.spdm");
            }

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

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

相关文章

Unity中的Destroy和DestroyImmediate的区别是什么?

在 Unity 中&#xff0c;Destroy 和 DestroyImmediate 都是用于销毁游戏对象&#xff08;GameObject&#xff09;、组件&#xff08;Component&#xff09;或资源的方法。在大多数情况下&#xff0c;建议优先使用 Destroy 方法&#xff0c;只有在确实需要立即销毁对象时才使用 …

Microk8s Ingress实现七层负载均衡

Microk8s Ingress是什么 Ingress是k8s的一种资源对象&#xff0c;用于管理外部对集群内服务的访问, 它通过提供一个统一的入口点&#xff0c;将外部流量路由到集群内部的不同服务。 Microk8s Ingress用于解决什么问题 k8s集群中服务默认只能在集群内访问。 如果需要从外部访…

DeepSpeek服务器繁忙?这几种替代方案帮你流畅使用!(附本地部署教程)

作者&#xff1a;后端小肥肠 目录 1. 前言 2. 解决方案 2.1. 纳米AI搜索&#xff08;第三方平台&#xff09; 2.2. Github&#xff08;第三方平台&#xff09; 2.3. 硅基流动&#xff08;第三方API&#xff09; 3. 本地部署详细步骤 3.1. 运行配置需求 3.2. 部署教程 4…

【大厂AI实践】美团:美团智能客服核心技术与实践

【大厂AI实践】美团&#xff1a;美团智能客服核心技术与实践 &#x1f31f; 嗨&#xff0c;你好&#xff0c;我是 青松 &#xff01; &#x1f308; 自小刺头深草里&#xff0c;而今渐觉出蓬蒿。 NLP Github 项目推荐&#xff1a; 【AI 藏经阁】&#xff1a;https://gitee.com…

科技查新有不通过的情况吗?为什么?

1. 科技查新有不通过的情况吗&#xff1f;为什么&#xff1f; 有。科技查新“不通过”&#xff08;即查新报告显示技术缺乏新颖性或存在侵权风险&#xff09;的情况并不罕见&#xff0c;主要原因包括&#xff1a; &#xff08;1&#xff09;技术缺乏创新性 重复开发&#xff…

批量提取 Word 文档中的页面

如何将 Word 文档中的页面提取出来形成一个新的文档呢&#xff1f;比如将 Word 文档中的第一页提取出来、将 Word 文档中的最后一页提取出来、再或者将 Word 文档中的中间几页提取出来等等。人工的处理肯定非常的麻烦&#xff0c;需要新建 Word 文档&#xff0c;然后将内容复制…

Spring统一格式返回

目录 一&#xff1a;统一结果返回 1&#xff1a;统一结果返回写法 2&#xff1a;String类型报错问题 解决方法 二&#xff1a;统一异常返回 统一异常返回写法 三&#xff1a;总结 同志们&#xff0c;今天咱来讲一讲统一格式返回啊&#xff0c;也是好久没有讲过统一格式返…

(十 八)趣学设计模式 之 观察者模式!

目录 一、 啥是观察者模式&#xff1f;二、 为什么要用观察者模式&#xff1f;三、 观察者模式的实现方式四、 观察者模式的优缺点五、 观察者模式的应用场景六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;…

Linux虚拟机网络配置-桥接网络配置

简介 本文档旨在指导用户如何在虚拟环境中配置Linux系统的桥接网络&#xff0c;以实现虚拟机与物理主机以及外部网络的直接通信。桥接网络允许虚拟机如同一台独立的物理机一样直接连接到物理网络&#xff0c;从而可以被分配一个独立的IP地址&#xff0c;并能够与网络中的其他设…

视频教育网站开源系统的部署安装 (roncoo-education)服务器为ubuntu22.04.05

一、说明 前端技术体系&#xff1a;Vue3 Nuxt3 Vite5 Vue-Router Element-Plus Pinia Axios 后端技术体系&#xff1a;Spring Cloud Alibaba2021 MySQL8 Nacos Seata Mybatis Druid redis 后端系统&#xff1a;roncoo-education&#xff08;核心框架&#xff1a;S…

线程相关八股

1. 线程和进程的区别&#xff1f; 进程&#xff1a;进程可以简单理解为进行一个程序&#xff0c;比如说我们打开一个浏览器&#xff0c;打开一个文本&#xff0c;这就是开启了一个进程&#xff0c;一个进程想要在计算机中运行&#xff0c;需要将程序交给CPU&#xff0c;将数据…

Python 绘制迷宫游戏,自带最优解路线

1、需要安装pygame 2、上下左右移动&#xff0c;空格实现物体所在位置到终点的路线&#xff0c;会有虚线绘制。 import pygame import random import math# 迷宫单元格类 class Cell:def __init__(self, x, y):self.x xself.y yself.walls {top: True, right: True, botto…

【音视频】VLC播放器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 一、vlc是什么&#xff1f; VLC Media Player&#xff08;简称VLC&#xff09;是一款免费、开源、跨平台的多媒体播放器&#xff0c;由非营利组织VideoLAN开发&#xff0c;最…

vue2+ele-ui实践

前言&#xff1a;真理先于实践&#xff0c;实践发现真理&#xff0c;再实践检验真理 环境&#xff1a;vue2 & element-ui 正片&#xff1a; Select 选择器 简称 下拉框 下拉框完整的使用循环 下拉框 → 点击下拉框 → 展示数据 → 选择数据 → 下拉框显示数据 核心具有…

刷题日记——部分二分算法题目分享

前言 咱们紧跟上一期结合时间复杂度浅谈二分法的好处, 并分享部分二分题目(将持续更新题目,绝对值你一个收藏)-CSDN博客 笔者接着分享一些刷过的关于二分算法的题目. 第一题 1283. 使结果不超过阈值的最小除数 - 力扣&#xff08;LeetCode&#xff09; 这道题就是典型的二…

excel 斜向拆分单元格

右键-合并单元格 右键-设置单元格格式-边框 在设置好分割线后&#xff0c;你可以开始输入文字。 需要注意的是&#xff0c;文字并不会自动分成上下两行。 为了达到你期望的效果&#xff0c;你可以通过 同过左对齐、上对齐 空格键或使用【AltEnter】组合键来调整单元格中内容的…

关于常规模式下运行VScode无法正确执行“pwsh”问题

前言&#xff1a; pwsh在系统环境中正确配置&#xff0c;且可以运行在cmd&#xff0c; powshell&#xff08;5.1&#xff09;--- 都需要在管理员权限下运行 &#xff08;打开setting&#xff09; 打开setting.json &#xff08;在vscode中添加 powershell 7 路径&…

企微审批中MySQL字段TEXT类型被截断的排查与修复实践

在MySQL中&#xff0c;TEXT类型字段常用于存储较大的文本数据&#xff0c;但在一些应用场景中&#xff0c;当文本内容较大时&#xff0c;TEXT类型字段可能无法满足需求&#xff0c;导致数据截断或插入失败。为了避免这种问题&#xff0c;了解不同文本类型&#xff08;如TEXT、M…

异常 PipeMapRed.waitOutputThreads(): subprocess failed with code 127

直接放问题异常 hadoop jar /opt/module/hadoop-3.3.2/share/hadoop/tools/lib/hadoop-streaming-3.3.2.jar \ -D mapreduce.map.memory.mb100 \ -D mapreduce.reduce.memory.mb100 \ -D mapred.map.tasks1 \ -D stream.num.map.output.key.fields2 \ -D num.key.fields.for.pa…

Focal Loss (聚焦损失) :解决类别不平衡与难易样本的利器,让模型学会“重点学习”

1. 为什么需要Focal Loss&#xff1f; 2. 交叉熵损失的问题 3.Focal Loss的智慧&#xff1a;给不同的错误“区别对待” 4.代码演示 1. 为什么需要Focal Loss&#xff1f; 在机器学习和深度学习中&#xff0c;类别不平衡&#xff08;Class Imbalance&#xff09; 是一个普遍…