MySQL執行過程中如何選擇最佳的執行路徑

本篇文章介紹一個非常核心的數據庫問題。MySQL 選擇最佳執行路徑(即“查詢優化”)的過程是由其查詢優化器(Query Optimizer) 完成的。

簡單來說,優化器的目標是:在多種可能的執行方案中,選擇一個它認為執行成本(Cost)最低的方案。

這個決策過程非常復雜,但可以概括為以下幾個核心步驟和原則:


一、核心流程:優化器如何工作?

1. 解析與重寫查詢
  • MySQL 首先解析 SQL 語句,生成一個解析樹。
  • 然后對解析樹進行重寫,包括一些語義優化,例如:
    • 視圖展開:將視圖引用替換為視圖的定義。
    • 簡化條件:移除不必要的括號、簡化表達式(如 5=5 AND a>0 被簡化為 a>0)。
    • 常量傳遞:利用等式的傳遞性進行簡化(如 a = 5 AND b = a => a = 5 AND b = 5)。
2. 生成可能的執行計劃
  • 對于同一個查詢,通常有多種執行方式。例如:
    • 表訪問方式:應該全表掃描(ALL)還是使用索引?(const, ref, range, index)。
    • 多表連接(JOIN)的順序:先讀哪張表,后讀哪張表?(A JOIN B 還是 B JOIN A)。
    • 多表連接的算法:使用 Nested-Loop JoinHash Join (MySQL 8.0+),還是 Batched Key Access Join
    • 子查詢優化:將子查詢轉換為更高效的 JOIN 操作。
    • 索引合并:是否需要對多個索引的掃描結果進行合并(index_merge)。

優化器會枚舉出許多(但不是全部,因為窮舉所有可能代價太高)可能的執行路徑。

3. 基于成本(Cost)評估執行計劃
  • 這是最核心的一步。優化器是一個基于成本的優化器(Cost-Based Optimizer, CBO)
  • 它會為每個執行計劃計算一個預估成本(Cost)。成本是一個相對值,主要基于以下統計信息:
    • I/O 成本:將數據從磁盤加載到內存的代價。全表掃描的成本主要來自這里。
    • CPU 成本:處理數據(比較記錄、排序、計算等)的代價。
    • 內存/資源成本:使用臨時表、排序等的代價。
4. 選擇成本最低的計劃
  • 優化器會比較所有生成的執行計劃的預估成本,并選擇它認為成本最低的那個。
  • 最終,這個被選中的計劃會被交給執行引擎去執行。

二、優化器依賴的關鍵信息

優化器的成本計算并非憑空猜測,它嚴重依賴于數據庫的統計信息

  1. 表統計信息

    • TABLE_ROWS:表的粗略行數。
    • DATA_LENGTH:表的數據大小。
    • 這些信息可以通過 ANALYZE TABLE table_name; 命令來更新,存儲在 information_schema.TABLES 中。
  2. 索引統計信息(至關重要)

    • 基數(Cardinality):索引中唯一值的估計值。這是一個非常關鍵的指標。
      • 高選擇性(High Cardinality):索引列的唯一值很多(如主鍵用戶名),意味著索引非常有效。
      • 低選擇性(Low Cardinality):索引列的唯一值很少(如性別狀態標志),使用索引可能不如全表掃描。
    • 索引信息存儲在 information_schema.STATISTICS 中。

示例SELECT * FROM users WHERE gender = 'F';

  • 如果 gender 列的基數很低(只有 ‘M’/‘F’ 兩個值),優化器知道即使用了索引,也要返回約50%的數據。此時全表掃描的成本可能更低。
  • 如果查詢是 SELECT * FROM users WHERE user_id = 123;user_id 是主鍵,基數極高,優化器會毫不猶豫地選擇主鍵索引進行查找。

三、開發者如何協助和干預優化器?

雖然優化器很強大,但它的決策基于統計信息,而統計信息可能是過時或不準確的。開發者可以這樣做:

  1. 提供合適的索引(最重要的手段)

    • WHERE, JOIN ... ON, ORDER BY, GROUP BY 子句中的列創建索引。
    • 使用覆蓋索引(Covering Index),即索引包含了查詢所需的所有字段,避免回表操作,極大提升性能。
  2. 及時更新統計信息

    • 在執行了大量 INSERT, UPDATE, DELETE 操作后,運行 ANALYZE TABLE table_name; 來更新統計信息,幫助優化器做出更準確的判斷。
  3. 優化SQL寫法

    • 避免使用 SELECT *,只選擇需要的列。
    • 謹慎使用 OR,它常常會導致索引失效,可以考慮使用 UNION 改寫。
    • 避免在索引列上使用函數或計算,這會導致索引失效(例如 WHERE YEAR(create_time) = 2023 不如 WHERE create_time >= '2023-01-01')。
  4. 使用優化器提示(Optimizer Hints)

    • 如果你確信優化器選錯了計劃,可以使用提示來強制干預。例如:
      • SELECT /*+ INDEX(table_name index_name) */ ...:強制使用某個索引。
      • SELECT /*+ NO_INDEX(table_name index_name) */ ...:強制忽略某個索引。
    • 注意: 這是一種高級且危險的操作,只有在充分理解和測試后才使用,因為數據分布變化后,強制提示可能反而會變差。
  5. 使用 EXPLAIN 分析計劃

    • 這是最強大的調試工具。在SQL語句前加上 EXPLAINEXPLAIN FORMAT=TREE (MySQL 8.0+),可以查看優化器選擇的執行計劃。
    • 你需要學會看 EXPLAIN 的輸出(尤其是 type, key, rows, Extra 字段),來判斷索引是否被有效利用、是否有全表掃描、是否使用了臨時表等。

總結

MySQL 通過查詢優化器選擇最佳執行路徑,其核心是:

  1. 基于成本模型:估算不同執行計劃的 I/O、CPU 成本。
  2. 依賴統計信息:表的行數、索引的基數等是其決策的依據。
  3. 目標是成本最低:選擇它認為執行最快的方案。

作為開發者,我們的職責是:

  • 提供準確的信息:通過創建合適的索引和更新統計信息來“幫助”優化器。
  • 驗證和干預:使用 EXPLAIN 工具驗證優化器的選擇,并在極少數情況下使用提示進行干預。
  • 編寫優化器友好的SQL:避免寫出讓優化器“困惑”的語句。

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

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

相關文章

【設計模式】從游戲角度開始了解設計模式 --- 抽象工廠模式

永遠記住,你的存在是有意義的, 你很重要, 你是被愛著的, 而且你為這個世界帶來了無可取代的東西。 -- 麥克西 《男孩、鼴鼠、狐貍和馬》-- 從零開始了解設計模式抽象工廠模式抽象工廠模式 今天我們一起來探究抽象工廠模式&#x…

tensorflow.js 使用場景

TensorFlow.js (簡稱 TF.js) 是一個利用 WebGL 和 Node.js 在瀏覽器和服務器端進行機器學習模型訓練和部署(推理)的 JavaScript 庫。它的核心價值在于將機器學習的能力帶入了 Web 開發者和 JavaScript 生態的領域。 其主要應用場景可以分為以下幾大類: 一、在瀏覽器中直接進…

詳解mcp以及agen架構設計與實現

文章目錄1.MCP概念2.MCP服務端主要能力3.MCP技術生態4.MCP與Function call區別5.MCP生命周期6.MCP java SDK7.MCP應用場景8.基于springAIollma阿里qianwenmcp設計私有AIAgent應用實現9.AI java項目落地技術選型10.構建AI Agent四大模塊11.LLM(大模型)與MCP之間關系12.A2A、MCP、…

六級第一關——下樓梯

上目錄: 目錄 題目描述 輸入格式 輸出格式 輸入輸出樣例 說明/提示 一、DP的意義以及線性動規簡介 在一個困難的嵌套決策鏈中,決策出最優解。 二、動態規劃性質淺談 三、子序列問題 (一)一個序列中的最長上升子序列&am…

【Linux基礎】Linux系統配置IP詳解:從入門到精通

目錄 1 Linux網絡配置概述 2 網卡配置文件位置和命名規則 2.1 配置文件位置 2.2 網卡命名規則 2.3 配置文件命名示例 3 網卡配置文件詳解 3.1 主要參數說明 4 Linux系統配置IP步驟 4.1 DHCP動態配置 4.2 靜態IP配置 5 Linux網絡配置流程 5.1 網絡配置流程 5.2 網卡…

C語言sprintf的高效替代方案

C語言的sprintf和snprintf將變量格式化輸出到內存buffer,其功能強大,用起來很方便。但sprintf系列函數的運行效率低下,主要包括四方面的原因:格式字符串解析、變參處理、locale(本地化)支持和通用&#xff…

【知識堂】制造業與物流數字化全景圖:系統縮寫大全與專業名詞速查手冊

前言在制造業和物流行業的數字化轉型過程中,我們經常會接觸到大量的 系統縮寫(如 ERP、MES、WMS…)和 專業名詞(如 AGV、BOM、LOT…)。 這些縮寫往往讓剛入行的人“一頭霧水”,即使是有經驗的從業者&#x…

利用JSONCrack與cpolar提升數據可視化及跨團隊協作效率

文章目錄前言1. 在Linux上使用Docker安裝JSONCrack2. 安裝Cpolar內網穿透工具3. 配置JSON Crack界面公網地址4. 遠程訪問 JSONCrack 界面5. 固定 JSONCrack公網地址前言 JSONCrack 是一款功能強大的開源數據可視化工具,專為解析和展示復雜的 JSON、XML 等結構化數據…

CANoe入門之一 CANoe功能概述

01 CANoe功能概述 CANoe軟件在汽車電子領域被廣泛應用。 CANoe軟件的全稱是CAN Open Environment,它是一個專業的系統級總線和ECU仿真、分析、開發、測試工具。支持ECU或總線網絡開發從需求分析到系統實現的全過程,包括模型創建、仿真、測試、診斷及通信…

項目管理核心八項(軟件篇)

2025年09月11日23:50:33:進來常思,寫代碼也五六年了,后面的路該何去何從呢? 項目管理核心八項一、項目管理之“建立開發人員 backup 機制”二、待補充一、項目管理之“建立開發人員 backup 機制” “建立開發人員 backup 機制” 是…

springboot redisson 分布式鎖入門與實戰

Spring Boot3 Redisson 項目地址 https://gitee.com/supervol/loong-springboot-study (記得給個start,感謝) Redisson 介紹 在分布式系統中,多節點部署的應用對共享資源(如數據庫記錄、緩存鍵、文件)的…

使用 Tkinter + Requests 實現地理信息安全系統學習時長助手

?重磅!盹貓的個人小站正式上線啦~誠邀各位技術大佬前來探秘!? 這里有: 硬核技術干貨:編程技巧、開發經驗、踩坑指南,帶你解鎖技術新姿勢!趣味開發日常:代碼背后的腦洞故事、工具…

構建一個優雅的待辦事項應用:現代JavaScript實踐

構建一個優雅的待辦事項應用:現代JavaScript實踐本文將介紹如何使用現代JavaScript(ES6)和DOM操作創建一個功能完整的待辦事項應用,無需任何外部庫或框架。功能概述添加新任務標記任務為完成/未完成編輯任務內容刪除任務過濾任務&…

【數據可視化-111】93大閱兵后的軍費開支情況———2024年全球軍費開支分析:用Python和Pyecharts打造炫酷可視化大屏

🧑 博主簡介:曾任某智慧城市類企業算法總監,目前在美國市場的物流公司從事高級算法工程師一職,深耕人工智能領域,精通python數據挖掘、可視化、機器學習等,發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

3.2.Maven-概述-介紹安裝

一.介紹:二.安裝:Maven的安裝比較簡單,因為他是綠色版的軟件,官方給我們提供Maven的安裝包就是一個zip壓縮包,在進行Maven安裝以及配置的時候,主要進行如下4步操作:第一步:把官方提供…

Kafka面試精講 Day 14:集群擴容與數據遷移

【Kafka面試精講 Day 14】集群擴容與數據遷移 在“Kafka面試精講”系列的第14天,我們將深入探討 Kafka 運維中最關鍵的操作之一:集群擴容與數據遷移。隨著業務增長,原始 Kafka 集群可能面臨磁盤不足、吞吐瓶頸或節點負載不均等問題&#xff…

字節一面 面經(補充版)

什么是RabbitMQ,特點是什么怎么理解保障消息的一致性String、StringBuffer、StringBuilder解釋一下線程安全先操作數據庫再刪緩存還是先刪緩存再操作數據庫這種辦法能杜絕數據不一致問題嗎解釋一下AOP介紹Redis的特點(Redis比較快)Redis為什么…

【MFC】對話框屬性:Absolute Align(絕對對齊)

前言 本文介紹對話框屬性中的Absolute Align(絕對對齊),同時給出相關示例便于理解。 目錄1 位置2 詳解3 示例1 位置 首先介紹一下這個屬性在哪里。 在資源視圖中雙擊對話框節點,打開該對話框; 鼠標右鍵工作區空白處,單擊屬性&…

【從0開始學習Java | 第17篇】集合(中-Set部分)

文章目錄Java集合之Set:無序不重復的元素容器一、Set接口的核心特性二、常用實現類及底層原理1. HashSet:基于哈希表的高效實現2. LinkedHashSet:保留插入順序的哈希實現3. TreeSet:基于紅黑樹的排序實現三、實現類對比與選擇建議…

玩轉Docker | 使用Docker部署dufs文件管理工具

玩轉Docker | 使用Docker部署dufs文件管理工具 前言 一、 dufs介紹 Dufs簡介 核心特性 ?? 靜態文件服務 ?? 文件夾打包下載 ?? 拖拽上傳文件/文件夾 ?? 文件在線創建、編輯與搜索 ? 斷點續傳與部分傳輸 ?? 細粒度訪問控制 ?? HTTPS 安全傳輸 ?? WebDAV 兼容支持…