一些SQL優化經驗(非添加索引版)

SQL 優化核心策略

偽代碼示例,現實比這個復雜

1. 子查詢優化

(1) 避免低效的?IN?和?NOT IN
  • 問題
    NOT IN?可能導致全表掃描,尤其是子查詢結果集較大時。

  • 優化方案

    • 替換為?LEFT JOIN

      -- 原查詢(低效)
      SELECT * FROM table_a 
      WHERE id NOT IN (SELECT id FROM table_b);-- 優化后
      SELECT a.* 
      FROM table_a a
      LEFT JOIN table_b b ON a.id = b.id
      WHERE b.id IS NULL;

    • 適用場景
      子查詢結果集較大,且關聯字段有索引。

(2) 優先使用?EXISTS?而非?IN
  • 優勢
    EXISTS?在找到第一條匹配后終止掃描,效率更高。

  • 示例

    -- 低效(子查詢結果集大時)
    SELECT * FROM users 
    WHERE id IN (SELECT user_id FROM orders);-- 高效
    SELECT * FROM users u
    WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);


2. JOIN 優化

(1) 減少?DISTINCT,改用?GROUP BY
  • 問題
    DISTINCT?可能導致全表排序和去重,內存消耗大。

  • 優化方案

    -- 低效
    SELECT DISTINCT user_id, order_date FROM orders;-- 高效(若需要聚合)
    SELECT user_id, order_date 
    FROM orders 
    GROUP BY user_id, order_date;

(2) 避免關聯字段使用函數或操作符
  • 問題
    關聯字段的表達式(如?||CONCAT)會導致索引失效。

  • 優化示例

    -- 低效
    SELECT DISTINCT user_id, order_date FROM orders;-- 高效(若需要聚合)
    SELECT user_id, order_date 
    FROM orders 
    GROUP BY user_id, order_date;
    -- 高效(直接字段匹配)
    SELECT * FROM table_a a
    JOIN table_b b ON a.ticket_no = b.ticket_no AND a.ticket_serial = b.ticket_serial;


3. 數據操作優化

(1) 增刪改寬表數據先創建臨時表

把先寫入后改的結果表的程序,改為一次性寫入,從而避免update操作鎖表

比如:

1.insert 結果表(大表)

2.update 結果表(大表)

改為:

insert 臨時表

update 臨時表

insert?結果表(大表)

復雜查詢改為:

1.insert 臨時表 1

2.insert 臨時表 2

3.insert 結果表 from 臨時表1 left join 臨時表2

把update ,delete結果表(大表)的語句延后執行,減少鎖表時間

比如:

1.update 或者 delete 結果表

2.許多待查詢的臨時表

3.insert 結果表

改為:

1.許多待查詢的臨時表

2.update 或者 delete 結果表

3.insert 寬表

(2) 類型轉換優化策略
核心原則:先篩選數據,后執行類型轉換

在 SQL 查詢中,優先通過原始字段類型完成數據篩選,將類型轉換操作推遲到最終結果處理階段。此策略可顯著減少需處理的數據量,提升性能。

優化優勢
  1. 減少計算開銷

    • 僅對篩選后的結果進行類型轉換,避免對全表數據的冗余處理。

    • 示例:若從 100 萬行數據中篩選出 1 萬行,類型轉換操作量減少 99%。

  2. 避免索引失效

    • 在?WHERE?或?JOIN?條件中對字段進行類型轉換(如?CAST(amount AS VARCHAR))會導致索引失效,引發全表掃描。

    • 優化后:直接基于原字段類型(如數值型?amount)篩選,確保索引生效。

  3. 降低內存與 IO 壓力

    • 大數據場景下,減少中間結果集的數據處理量,降低內存和磁盤 IO 負載。

具體策略

篩選階段保持字段原生類型,轉換放在最后

-- 先篩選,再轉換
SELECT id, CAST(created_at AS DATE) AS create_date  -- 轉換放在最后
FROM orders 
WHERE created_at >= '2023-01-01';           -- 用原生類型過濾

4. 表設計與維護

(1) 統一關聯字段類型
  • 問題
    字段類型不匹配(如?INT?vs?VARCHAR)會導致隱式轉換和性能下降。

  • 優化方案
    與上游協商統一字段類型

(2) 視圖轉結果表
  • 場景
    高頻查詢的復雜視圖(如報表接口)。

  • 優化步驟

    1. 將視圖轉為結果表:

      在查詢結果表之前 用存儲過程將結果寫入結果表,然后再進行查詢
    2. 查詢時直接查詢結果表,提升查詢效果


5. 內存與 IO 優化

(1) 合理使用臨時表


內存臨時表減少磁盤 IO,但需注意內存容量。

(2) 分頁查詢優化
  • 避免?OFFSET?深度分頁
    使用?WHERE?條件+游標方式(如基于時間或主鍵)。

-- 低效(OFFSET 100000)
SELECT * FROM orders ORDER BY id LIMIT 10 OFFSET 100000;-- 高效(基于上次查詢的末尾 ID)
SELECT * FROM orders 
WHERE id > 100000 
ORDER BY id 
LIMIT 10;

6. 定期維護統計信息


更新表的統計信息(如?ANALYZE table),幫助優化器生成高效計劃。?

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/diannao/75583.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/diannao/75583.shtml
    英文地址,請注明出處:http://en.pswp.cn/diannao/75583.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    <項目> 高并發服務器的HTTP協議支持

    目錄 HTTP模塊 模塊劃分與介紹 模塊實現 Util模塊 HTTPRequest模塊 HTTPResponse模塊 HTTPContext模塊 ParseHttpLine RecvHttpLine RecvHttpHead ParseHttpHead RecvHttpBody 對外接口 HttpServer模塊 OnConnected OnMessage Route IsFileHandler FileHandler Dispatcher …

    基于Spring Boot + Vue的銀行管理系統設計與實現

    基于Spring Boot Vue的銀行管理系統設計與實現 一、引言 隨著金融數字化進程加速,傳統銀行業務向線上化轉型成為必然趨勢。本文設計并實現了一套基于Spring Boot Vue的銀行管理系統,通過模塊化架構滿足用戶、銀行職員、管理員三類角色的核心業務需求…

    微軟提出 Logic-RL:基于規則的強化學習釋放大語言模型推理能力

    ? 更多 LLM 架構文章點擊查看: LLM 架構專欄 大模型架構專欄文章閱讀指南 1. AI 智能體,顛覆還是賦能?一文讀懂! 2. 1W8000 字 解鎖 AI 高效運作密碼:工作流與智能體如何協同? 3. 萬字深度剖析 AI 代理&am…

    STM32八股【1】-----啟動流程和startup文件理解

    啟動流程 知識點 MCU 上電復位。MSP從向量表第0個地址讀取一個32位(2字節)的值并保存,該值為棧頂地址。PC計數器從第1個地址讀取一個兩字節的值并保存,該值為程序入口,一般是Reset_Handler。想了解FLASH地址映射可以…

    詳解c++20的協程,自定義可等待對象,生成器詳解

    協程 c20的協程三大標簽:“性能之優秀”,“開發之靈活”,“門檻之高” 在講解c的協程使用前,我們需要先明白協程是什么,協程可以理解為用戶態的線程,它需要由程序來進行調度,如上下文切換與調…

    JavaEE企業級開發 延遲雙刪+版本號機制(樂觀鎖) 事務保證redis和mysql的數據一致性 示例

    提醒 要求了解或者熟練掌握以下知識點 spring 事務mysql 臟讀如何保證緩存和數據庫數據一致性延遲雙刪分布式鎖并發編程 原子操作類 前言 在起草這篇博客之前 我做了點功課 這邊我寫的是一個示例代碼 數據層都寫成了 mock 的形式(來源于 JUnit5) // Dduo import java.u…

    A2 最佳學習方法

    記錄自己想法的最好理由是發現自己的想法,并將其組織成可傳播的形式 (The best reason for recording what one thinks is to discover what one thinks and to organize it in transmittable form.) Prof Ackoff 經驗之談: 做培訓或者寫文章&#xff…

    嵌入式硬件工程師從小白到入門-PCB繪制(二)

    PCB繪制從小白到入門:知識點速通與面試指南 一、PCB設計核心流程 需求分析 明確電路功能(如電源、信號處理、通信)。確定關鍵參數(電壓、電流、頻率、接口類型)。 原理圖設計 元器件選型:匹配封裝、電壓、…

    vue創建子組件步驟及注意事項

    在 Vue 中創建子組件需要遵循組件化開發的核心原則,并注意數據流、通信機制、復用性等關鍵點。以下是詳細步驟和注意事項,結合代碼示例說明: 一、創建子組件的步驟 1. 定義子組件 創建一個 .vue 文件(單文件組件)&am…

    Cocos Creator版本發布時間線

    官網找不到,DeepSeek給的答案,這里做個記錄。 Cocos Creator 1.x 系列 發布時間:2016 年 - 2018 年 1.0(2016 年 3 月): 首個正式版本,基于 Cocos2d-x 的 2D 游戲開發工具鏈,集成可…

    【Spring AI】基于專屬知識庫的RAG智能問答小程序開發——功能優化:用戶鑒權主體功能開發

    系列文章目錄 【Spring AI】基于專屬知識庫的RAG智能問答小程序開發——完整項目(含完整前端后端代碼)【Spring AI】基于專屬知識庫的RAG智能問答小程序開發——代碼逐行精講:核心ChatClient對象相關構造函數【Spring AI】基于專屬知識庫的R…

    【AI神經網絡】深度神經網絡(DNN)技術解析:從原理到實踐

    引言 深度神經網絡(Deep Neural Network, DNN)作為人工智能領域的核心技術,近年來在計算機視覺、自然語言處理、醫療診斷等領域取得了突破性進展。與傳統機器學習模型相比,DNN通過多層非線性變換自動提取數據特征,解決…

    目標跟蹤——deepsort算法詳細闡述

    deepsort 算法詳解 Unmatched Tracks(未匹配的軌跡) 本質角色: 是已存在的軌跡在當前幀中“失聯”的狀態,即預測位置與檢測結果不匹配。 生命周期階段: 已初始化: 軌跡已存在多幀,可能攜帶歷史信息(如外觀特征、運動模型)。 未被觀測到: 當前幀中未找到對應的檢測框…

    Vue-admin-template安裝教程

    #今天配置后臺管理模板發現官方文檔的鏡像網站好像早失效了,自己稍稍總結了一下方法# 該項目環境需要node17及以下,如果npm install這一步報錯可能是這個原因 git clone https://github.com/PanJiaChen/vue-admin-template.git cd vue-admin-template n…

    Rust從入門到精通之進階篇:14.并發編程

    并發編程 并發編程允許程序同時執行多個獨立的任務,充分利用現代多核處理器的性能。Rust 提供了強大的并發原語,同時通過類型系統和所有權規則在編譯時防止數據競爭和其他常見的并發錯誤。在本章中,我們將探索 Rust 的并發編程模型。 線程基…

    算法訓練營第二十三天 | 貪心算法(一)

    文章目錄 一、貪心算法理論基礎二、Leetcode 455.分發餅干二、Leetcode 376. 擺動序列三、Leetcode 53. 最大子序和 一、貪心算法理論基礎 貪心算法是一種在每一步選擇中都采取當前狀態下的最優決策,從而希望最終達到全局最優解的算法設計技術。 基本思想 貪心算…

    css基礎-display 常用布局

    CSS display 屬性詳解 屬性設置元素是否被視為塊級或行級盒子以及用于子元素的布局,例如流式布局、網格布局或彈性布局。 一、基礎顯示模式 1. block 作用: 元素獨占一行可設置寬高和內外邊距默認寬度撐滿父容器 應用場景: 布局容器&a…

    速賣通API數據清洗實戰:從原始JSON到結構化商品數據庫

    下面將詳細介紹如何把速賣通 API 返回的原始 JSON 數據清洗并轉換為結構化商品數據庫。 1. 數據獲取 首先要借助速賣通 API 獲取商品數據,以 Python 為例,可使用requests庫發送請求并得到 JSON 數據。 import requests# 替換為你的 API Key 和 Secret …

    【零基礎入門unity游戲開發——2D篇】2D物理系統 —— 2D剛體組件(Rigidbody2D)

    考慮到每個人基礎可能不一樣,且并不是所有人都有同時做2D、3D開發的需求,所以我把 【零基礎入門unity游戲開發】 分為成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要講解C#的基礎語法,包括變量、數據類型、運算符、流程控制、面向對象等,適合沒有編程基礎的…

    Collectors.toMap / list 轉 map

    前言 略 Collectors.toMap List<User> userList ...; Map<Long, User> userMap userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));假如id存在重復值&#xff0c;則會報錯Duplicate key xxx, 解決方案 兩個重復id中&#…