SQL等价改写优化

or 与 union all的优化
在SQL开发中,我们经常会遇到这样的情况:需要组合多个相似但略有不同的查询结果。大多数开发者本能地使用UNION/UNION ALL来解决,这种方式直观易懂,但在特定场景下却隐藏着巨大的性能浪费。

本案例将从执行原理层面,深入剖析为什么在某些情况下,OR条件能比UNION ALL带来质的性能提升。

  • 第一部分:查询dcc_sys_log表中cause条件为"对端被关闭%"的记录
    select peer_id 对端标识,
    null 源域名,
    null 目标域名,
    alert_type 告警类型,
    log_time 告警时间,
    cause 告警内容,
    deal_log 处理状态,
    deal_staff 处理人,
    deal_time 处理时间,
    remark 备注
    from dcc_sys_log
    where action = ‘disconnect’
    and cause like ‘对端被关闭%’
    and deal_log = ‘deal_log’
    and alert_type = ‘alert_type’
    and log_time >= TO_DATE(‘2024-08-02’, ‘YYYY-MM-DD’)
    and log_time < TO_DATE(‘2024-08-03’, ‘YYYY-MM-DD’) + 1
    – 第二部分:查询dcc_ne_log表中result=0的记录
    union
    (select peer_id 对端标识,
    origin_host 源域名,
    dest_host 目标域名,
    alert_type 告警类型,
    log_time 告警时间,
    cause 告警内容,
    deal_log 处理状态,
    deal_staff 处理人,
    deal_time 处理时间,
    remark 备注
    from dcc_ne_log
    where result = 0
    and cause like ‘parser失败%’
    and deal_log = ‘deal_log’
    and alert_type = ‘alert_type’
    and log_time >= TO_DATE(‘2024-08-02’, ‘YYYY-MM-DD’)
    and log_time < TO_DATE(‘2024-08-03’, ‘YYYY-MM-DD’) + 1)
    union
    – 第三部分:查询dcc_ne_log表中result_code特定值的记录
    (select peer_id 对端标识,
    origin_host 源域名,
    dest_host 目标域名,
    alert_type 告警类型,
    log_time 告警时间,
    cause 告警内容,
    deal_log 处理状态,
    deal_staff 处理人,
    deal_time 处理时间,
    remark 备注
    from dcc_ne_log
    where result_code = ‘DIAMETER_UNABLE_TO_DELIVER’
    and svcctx_id like ‘SR-Timeout%’
    and deal_log = ‘deal_log’
    and alert_type = ‘alert_type’
    and log_time >= TO_DATE(‘2024-08-02’, ‘YYYY-MM-DD’)
    and log_time < TO_DATE(‘2024-08-03’, ‘YYYY-MM-DD’) + 1)
    union
    – 第四部分:查询dcc_sys_log表中cause条件为"接收消息异常%"的记录
    (select peer_id 对端标识,
    null 源域名,
    null 目标域名,
    alert_type 告警类型,
    log_time 告警时间,
    cause 告警内容,
    deal_log 处理状态,
    deal_staff 处理人,
    deal_time 处理时间,
    remark 备注
    from dcc_sys_log
    where action = ‘disconnect’
    and cause like ‘接收消息异常%’
    and deal_log = ‘deal_log’
    and alert_type = ‘alert_type’
    and log_time >= TO_DATE(‘2024-08-02’, ‘YYYY-MM-DD’)
    and log_time < TO_DATE(‘2024-08-03’, ‘YYYY-MM-DD’) + 1)

分析问题
这段SQL的执行过程实际上是:

  1. 四次独立的表扫描:
  • 两次对dcc_sys_log表的完整扫描

  • 两次对dcc_ne_log表的完整扫描

  1. 四次过滤操作:
  • 每个子查询各自应用WHERE条件进行过滤
  1. 三次合并操作:
  • 对四个结果集执行UNION操作,包含排序和去重
  1. 四次重复的公共条件判断:
  • deal_log = ‘deal_log’

  • alert_type = ‘alert_type’

  • 相同的时间范围条件

这种写法的效率问题主要体现在:相同表被多次无谓地扫描,公共条件被重复判断,导致CPU和I/O资源的严重浪费。

精准优化:拆解和合并
经过分析,我们可以看到明显的优化空间:

  1. 相同表的查询合并:
  • 第一部分和第四部分都查询dcc_sys_log表

  • 第二部分和第三部分都查询dcc_ne_log表

  1. 差异点隔离:
  • dcc_sys_log表的差异仅在于cause条件

  • dcc_ne_log表的差异在于result/result_code/svcctx_id条件组合

将这些相似查询通过OR条件合并后的SQL:

– 第一部分:合并对dcc_sys_log的两次查询
select peer_id 对端标识,
null 源域名,
null 目标域名,
alert_type 告警类型,
log_time 告警时间,
cause 告警内容,
deal_log 处理状态,
deal_staff 处理人,
deal_time 处理时间,
remark 备注
from dcc_sys_log
where action = ‘disconnect’
and (cause like ‘对端被关闭%’ or cause like ‘接收消息异常%’)
and deal_log = ‘deal_log’
and alert_type = ‘alert_type’
and log_time >= TO_DATE(‘2024-08-02’, ‘YYYY-MM-DD’)
and log_time < TO_DATE(‘2024-08-03’, ‘YYYY-MM-DD’) + 1
union
– 第二部分:合并对dcc_ne_log的两次查询
select peer_id 对端标识,
origin_host 源域名,
dest_host 目标域名,
alert_type 告警类型,
log_time 告警时间,
cause 告警内容,
deal_log 处理状态,
deal_staff 处理人,
deal_time 处理时间,
remark 备注
from dcc_ne_log
where ((result = 0 and cause like ‘parser失败%’) – 第一个差异条件组合
or (result_code = ‘DIAMETER_UNABLE_TO_DELIVER’ and svcctx_id like ‘SR-Timeout%’)) – 第二个差异条件组合
and deal_log = ‘deal_log’
and alert_type = ‘alert_type’
and log_time >= TO_DATE(‘2024-08-02’, ‘YYYY-MM-DD’)
and log_time < TO_DATE(‘2024-08-03’, ‘YYYY-MM-DD’) + 1
实际应用中的注意事项

  1. 括号使用:在复杂OR条件组合中,正确使用括号确保逻辑正确

where ((result = 0 and cause like ‘parser失败%’)
or (result_code = ‘DIAMETER_UNABLE_TO_DELIVER’ and svcctx_id like ‘SR-Timeout%’))
and deal_log = ‘deal_log’
2. OR vs AND优先级:OR条件比AND优先级低,必要时使用括号明确优先级

  1. 处理NULL值:当OR条件两侧涉及NULL值判断时,需特别注意逻辑正确性

  2. 验证结果一致性:务必确认优化前后结果完全一致

  3. 索引使用情况:通过执行计划检查OR条件是否影响了索引使用

优化效果分析
这个优化带来了几个明显的好处:

  1. 表扫描次数减少:原来需要扫描dcc_sys_log表2次,dcc_ne_log表2次,现在各只需扫描1次

  2. I/O减少:减少了50%的表扫描,相应减少了磁盘I/O操作

  3. 代码简化:代码行数从34行减少到24行,更加简洁易读

  4. 排序操作减少:UNION操作需要对结果进行排序去重,合并后的查询能减少排序工作量

小结
本例通过OR条件替代UNION操作,减少表扫描次数。这种简单却有效的优化方法,在实际工作中经常被忽视。通过识别SQL中的重复访问模式,将相似条件的查询合并,我们可以在不改变业务逻辑的前提下,显著提升SQL执行效率。

在实际优化工作中,建议首先尝试通过EXPLAIN PLAN分析查询性能,然后再决定是使用OR条件还是保留UNION结构,以获得最佳性能。

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

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

相关文章

【已解决】 数据库INSERT操作时,Column count doesn’t match value count at row 1

【已解决】数据库INSERT操作时&#xff0c;ColumnColumn count doesn’t match value count at row 1 在开发过程中&#xff0c;我们经常会遇到数据库操作错误&#xff0c;其中之一就是 MySQL 中的 “Column count doesn’t match value count at row1” 错误。这个错误通常发…

管件接头的无序抓取

文章目录 1&#xff0c;目的2&#xff0c;过程3&#xff0c;易混易错点4&#xff0c;代码详解4.1&#xff0c;初始化窗口4.2&#xff0c;创建多视角立体视觉模型。4.3&#xff0c;创建表面匹配模型4.4&#xff0c;多视角立体视觉重建管件堆表面模型4.5&#xff0c;管道接头查找…

移远通信 × 紫光展锐,推动FWA “5G+AI”新体验

6月19日&#xff0c;在2025 MWC上海期间&#xff0c;移远通信宣布&#xff0c;携手紫光展锐&#xff0c;推出面向下一代CPE应用的“5GAI”融合解决方案。目前双方正联合多家CPE厂商开展方案深度调优&#xff0c;以加速5GAI CPE终端的产业化落地进程。 该方案以移远5G模组RG620…

深入理解Grad-CAM:用梯度可视化神经网络的“注意力“

深入理解Grad-CAM&#xff1a;用梯度可视化神经网络的"注意力" 引言 在深度学习的发展过程中&#xff0c;模型的可解释性一直是一个重要的研究方向。尽管现代神经网络在图像识别、自然语言处理等任务上取得了令人瞩目的成果&#xff0c;但它们往往被称为"黑盒…

离线环境jenkins构建前端部署镜像

gitlabjenkins 实现前端项目打包成 docker 镜像&#xff1b;gitlab部署就不赘述了&#xff1b;因部署的gitlab版本的webhooks有问题&#xff0c;无法进行配置,所以文章的构建是手动触发的。并且nodejs部署应该也能跟docker一样直接安装进jenkins的镜像(但是多版本可能就有其他问…

案例:塔能科技×某市智能照明——从传统亮化到智慧光生态的跨越

在城市发展的滚滚浪潮中&#xff0c;市政照明不仅是驱散黑夜的光明使者&#xff0c;更是衡量城市智能化水平的关键标尺。贵州某市的城市照明系统正经历一场意义深远的革新&#xff0c;塔能科技以创新科技为核心驱动力&#xff0c;为这座城市的夜间照明生态注入全新活力。通过智…

LeapMotion-HandPoseRecorder 脚本详解

HandPoseRecorder 脚本详解 这个脚本是一个用于在 Unity 中录制和保存 Leap Motion 手部姿势的工具。下面我将详细解释脚本的各个部分: 核心功能 该脚本的主要作用是: 从 Leap Motion 设备捕获当前手部姿势数据 将姿势数据序列化为可重用的 ScriptableObject 在 Unity 项目…

【Guava】0.做自己的编程语言

【Guava】0.做自己的编程语言 0.前言1.明确你的目标1.2.设计1.3.写一个介绍 2.开始吧&#xff01; 0.前言 DO WHAT THE F**K YOU WANT TO DO 我相信&#xff0c;网上有许多各式各样的做自己的编程语言教程&#xff0c;but 都是这样 收费 shit 本教程教你真正教你实现一个名叫G…

【软考高级系统架构论文】论无服务器架构及其应用

论文真题 近年来&#xff0c;随着信息技术的迅猛发展和 应用需求的快速更迭&#xff0c;传统的多层企业应用系统架构面临越来越多的挑战&#xff0c;已经难以适应这种变化。在这一背景下&#xff0c;无服务器架构(Serverless Architecture) 逐渐流行&#xff0c;它强调业务逻辑…

国产MCU A\B SWAP原理及实操

看到有读者留言说还是没理清A\B SWAP的原理。 今天就以某国产MCU为例&#xff0c;实际演示一番&#xff0c;看看大家在芯片设计时思路是什么。 我们首先回顾下SWAP的基本思想。 SWAP的基本思想是将PFLASH分成两组Bank&#xff0c;Bank A(假设是active)和Bank B(假设是inacti…

目标检测neck经典算法之FPN的源码实现

┌────────────────────────────────────────────────────┐│ 初始化构造 (__init__) │└─────────────────────────────────────────────…

extern关键字:C/C++跨文件编程利器

在 C 和 C 中&#xff0c;extern 是一个关键字&#xff0c;用于声明变量或函数是在其他文件中定义的。它主要用于实现多个源文件之间的符号共享。 目录 &#x1f4cc; 一、C语言中的 extern 1. 基本作用 2. 示例说明 定义全局变量&#xff08;只在一个 .c 文件中&#xff…

编程语言的演化与选择:技术浪潮中的理性决策

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;为什么“选对语言”比“掌握语言”更重要&#xff1f; 在软件开发的世界里&#xff0c;语言是一切的基础。…

【StarRocks系列】StarRocks vs Mysql

目录 StarRocks 简介 核心特性 典型应用场景 StarRocks vs MySQL&#xff1a;核心区别详解 关键差异总结 如何选择&#xff1f; StarRocks 简介 StarRocks 是一款高性能、全场景、分布式、实时分析型的数据库&#xff08;MPP - 大规模并行处理&#xff09;。它诞生于解决…

Axios 知识点全面总结

文章目录 Axios 知识点全面总结一、Axios 基础概念1. 什么是 Axios&#xff1f;2. 核心特性 二、安装与基本用法1. 安装2. 基本请求示例 三、请求方法与参数四、请求配置选项&#xff08;config&#xff09;五、拦截器&#xff08;Interceptors&#xff09;六、错误处理七、取消…

【软考高级系统架构论文】论 SOA 在企业集成架构设计中的应用

论文真题 企业应用集成(Enterprise Application Integration, EAI)是每个企业都必须要面对的实际问题。面向服务的企业应用集成是一种基于面向服务体系结构(Service - Oriented Architecture, SOA)的新型企业应用集成技术,强调将企业和组织内部的资源和业务功能暴露为服务,实…

springboot 提供的可扩展接口

一、spring 和 springboot Spring框架提供了全面的基础架构支持。包含依赖注入和开箱即用等模块&#xff0c;如&#xff1a;Spring JDBC 、Spring MVC 、Spring Security、 Spring AOP 、Spring ORM 、Spring Test Spring Boot 约定大于配置-----消除了设置Spring应用程序所需…

python学习打卡day55

DAY 55 序列预测任务介绍 知识点回顾 序列预测介绍 单步预测多步预测的2种方式 序列数据的处理&#xff1a;滑动窗口多输入多输出任务的思路经典机器学习在序列任务上的劣势&#xff1b;以随机森林为例 作业&#xff1a;手动构造类似的数据集&#xff08;如cosx数据&#xff09…

Leetcode hot100 Java刷题

文章目录 快排146. LRU 缓存acm模式树的前中后序遍历acm模式链表的基本操作1. 两数之和49. 字母异位词分组128. 最长连续序列283. 移动零11. 盛最多水的容器15. 三数之和42. 接雨水53. 最大子数组和56. 合并区间73. 矩阵置零48. 旋转图像141. 环形链表142. 环形链表 II24. 两两…

Linux 命令详解 —— 进程管理

文章目录 精通Linux操作系统(以Centos7为例)进程管理ps常用组合进程状态 STAT 详解高级筛选与格式化输出按条件过滤进程自定义输出字段显示进程树关系排障场景定位高 CPU检查僵尸进程查看进程的线程查看进程打开的文件/网络连接常用组合速查top前5摘要区进程列表信息交互式命令…