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
英文地址,請注明出處:http://en.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摘要區進程列表信息交互式命令…