一、MySQL 8.0 之《EXPLAIN ANALYZE 執行計劃》

文章目錄

  • 一、MySQL EXPLAIN ANALYZE 執行計劃指南
    • 主要功能
      • 實際執行性能分析
      • 詳細的執行統計
      • 性能瓶頸識別
    • 與普通 EXPLAIN 的區別
    • 使用場景
      • 查詢優化
      • 問題診斷
    • 總結
  • 二、EXPLAIN ANALYZE 執行計劃
    • 樣例
    • 分析
      • 執行順序解讀
      • 逐行詳細解釋
        • 第 7 行 (最內層)
        • 第 6 行
        • 第 5 行
        • 第 4 行
        • 第 3 行
        • 第 2 行
        • 第 1 行 (最外層)
      • 總結與性能分析


一、MySQL EXPLAIN ANALYZE 執行計劃指南

MySQL 的 EXPLAIN ANALYZE 是一個強大的查詢分析工具,它提供了比傳統 EXPLAIN 更詳細的查詢執行信息。

主要功能

實際執行性能分析

  • 不僅顯示預估的執行計劃,還會實際執行查詢并收集真實的性能數據
  • 提供每個操作的實際執行時間、處理行數等精確信息

詳細的執行統計

  • 顯示每個步驟的實際成本(actual cost)
  • 提供實際處理的行數與估計行數的對比
  • 展示每個操作的實際執行時間

性能瓶頸識別

  • 快速定位查詢中最耗時的操作
  • 識別全表掃描、不必要的排序等性能問題
  • 找出索引使用不當的情況

與普通 EXPLAIN 的區別

EXPLAIN 只是分析執行計劃而不實際執行查詢,而 EXPLAIN ANALYZE 會真正執行查詢,因此:

  • 提供更準確的性能數據
  • 能發現優化器估算錯誤的情況
  • 但執行時間會更長,特別是對于復雜查詢

使用場景

查詢優化

  • 對比不同索引策略的實際效果
  • 驗證查詢重寫是否真正提升性能
  • 分析復雜 JOIN 查詢的執行效率

問題診斷

  • 排查慢查詢的根本原因
  • 識別數據分布不均勻導致的性能問題
  • 發現統計信息過時的情況

總結

EXPLAIN ANALYZE 是數據庫性能調優和查詢優化的重要工具,能幫助你從估算轉向基于實際數據的優化決策。通過提供真實的執行統計信息,它讓數據庫性能分析更加準確和可靠。


二、EXPLAIN ANALYZE 執行計劃

樣例

-> Sort: <temporary>.Population DESC (actual time=8.306..8.431 rows=125 loops=1)-> Stream results (actual time=0.145..8.033 rows=125 loops=1)-> Nested loop inner join (cost=241.12 rows=205) (actual time=0.141..7.787 rows=125 loops=1)-> Filter: (world.country.Continent = 'Asia') (cost=25.40 rows=34) (actual time=0.064..0.820 rows=51 loops=1)-> Table scan on country (cost=25.40 rows=239) (actual time=0.059..0.359 rows=239 loops=1)-> Filter: (world.city.Population > 1000000) (cost=4.53 rows=6) (actual time=0.030..0.131 rows=2 loops=51)-> Index lookup on city using CountryCode (CountryCode=world.country.`Code`) (cost=4.53 rows=18) (actual time=0.023..0.096 rows=35 loops=51)

分析

我們來詳細解讀這個 MySQL 的 EXPLAIN ANALYZE 執行計劃。

這個執行計劃展示了數據庫為了執行一個查詢而采取的具體步驟、成本估算以及(因為有 actual time)實際的執行時間和處理行數。

首先,根據執行計劃我們可以推斷出原始的 SQL 查詢大致是這樣的:

EXPLAIN ANALYZE
SELECT-- ... some columns from city and country
FROMcity
INNER JOINcountry ON city.CountryCode = country.Code
WHEREcountry.Continent = 'Asia'AND city.Population > 1000000
ORDER BYcity.Population DESC;

執行順序解讀

數據庫執行計劃的讀取順序是 從內到外,從上到下。也就是說,縮進最深的步驟最先執行。執行流程如下:

  1. 掃描 country 表 (Line 5)
  2. 過濾出 Continent = 'Asia' 的國家 (Line 4)
  3. 對于每一個亞洲國家,去 city 表中查找對應的城市 (Line 7)
  4. 過濾出人口大于一百萬的城市 (Line 6)
  5. 將上面兩步(3和4)組合成一個嵌套循環連接 (Line 3)
  6. 將連接后的結果進行流式處理 (Line 2)
  7. 對最終結果按 Population 降序排序 (Line 1)

逐行詳細解釋

第 7 行 (最內層)
-> Index lookup on city using CountryCode (CountryCode=world.country.`Code`) (cost=4.53 rows=18) (actual time=0.023..0.096 rows=35 loops=51)
  • 操作: Index lookup on city using CountryCode
    • 含義: 這是嵌套循環的內層操作。數據庫正在使用 city 表上的 CountryCode 索引來查找與外層(country 表)匹配的行。連接條件是 city.CountryCode = country.Code
  • 成本估算: (cost=4.53 rows=18)
    • 含義: 優化器估計每次執行這個查找操作的成本是 4.53,并且估計平均每次能找到 18 行。
  • 實際執行: (actual time=0.023..0.096 rows=35 loops=51)
    • actual time=0.023..0.096: 第一次執行此操作耗時 0.023 毫秒,所有執行中最長的一次耗時 0.096 毫秒。
    • rows=35: 實際上平均每次查找返回了 35 行。這說明優化器的估計(18行)偏低了。
    • loops=51: 這個操作被執行了 51 次。這非常關鍵,它告訴我們上一步(過濾國家)產生了 51 行結果。
第 6 行
-> Filter: (world.city.Population > 1000000) (cost=4.53 rows=6) (actual time=0.030..0.131 rows=2 loops=51)
  • 操作: Filter: (world.city.Population > 1000000)
    • 含義: 對上一步(Index lookup)返回的城市結果進行過濾,只保留人口 (Population) 大于 1,000,000 的城市。
  • 成本估算: (cost=4.53 rows=6)
    • 含義: 優化器估計在找到的城市中,平均有 6 個城市的人口會超過一百萬。
  • 實際執行: (actual time=0.030..0.131 rows=2 loops=51)
    • rows=2: 實際上平均每次只有 2 個城市滿足人口條件。
    • loops=51: 這個過濾操作同樣被執行了 51 次,與上一步的循環次數一致。
第 5 行
-> Table scan on country (cost=25.40 rows=239) (actual time=0.059..0.359 rows=239 loops=1)
  • 操作: Table scan on country
    • 含義: 這是嵌套循環的外層驅動操作的起點。數據庫正在執行全表掃描,即讀取 country 表中的每一行。
  • 成本估算: (cost=25.40 rows=239)
    • 含義: 優化器估計全表掃描的成本是 25.40,并估計 country 表總共有 239 行。
  • 實際執行: (actual time=0.059..0.359 rows=239 loops=1)
    • rows=239: 實際上確實掃描了 239 行。
    • loops=1: 這個全表掃描操作只執行了 1 次。
第 4 行
-> Filter: (world.country.Continent = 'Asia') (cost=25.40 rows=34) (actual time=0.064..0.820 rows=51 loops=1)
  • 操作: Filter: (world.country.Continent = 'Asia')
    • 含義: 對上一步(全表掃描)的結果進行過濾,只保留 Continent 字段為 ‘Asia’ 的國家。
  • 成本估算: (cost=25.40 rows=34)
    • 含義: 優化器估計會有 34 個亞洲國家。
  • 實際執行: (actual time=0.064..0.820 rows=51 loops=1)
    • rows=51: 實際上找到了 51 個亞洲國家。這個數字(51)成為了內層循環(Index lookupFilter)的 loops 次數。
    • loops=1: 這個過濾操作也只執行了 1 次。
第 3 行
-> Nested loop inner join (cost=241.12 rows=205) (actual time=0.141..7.787 rows=125 loops=1)
  • 操作: Nested loop inner join
    • 含義: 這是一個總結行,表示數據庫使用了嵌套循環連接算法。它將上面兩個分支(過濾后的 country 表和過濾后的 city 表)的結果連接起來。
  • 成本估算: (cost=241.12 rows=205)
    • 含義: 優化器估計整個連接操作的總成本是 241.12,最終會產生 205 行結果。
  • 實際執行: (actual time=0.141..7.787 rows=125 loops=1)
    • rows=125: 實際上,整個連接操作最終產生了 125 行結果(51個亞洲國家中,總共有125個城市人口超百萬)。
    • loops=1: 整個連接過程作為一個整體,執行了 1 次。
第 2 行
-> Stream results (actual time=0.145..8.033 rows=125 loops=1)
  • 操作: Stream results
    • 含義: 這是一個中間步驟,將連接操作產生的 125 行結果以流的形式傳遞給下一個操作(排序)。
  • 實際執行: (actual time=... rows=125 loops=1)
    • 它處理了 125 行數據,耗時反映了從接收第一行到傳遞完最后一行的時間。
第 1 行 (最外層)
-> Sort: <temporary>.Population DESC (actual time=8.306..8.431 rows=125 loops=1)
  • 操作: Sort: <temporary>.Population DESC
    • 含義: 這是查詢的最后一步。數據庫對前序步驟傳來的 125 行結果,按照 Population 字段進行降序排序 (DESC)。
    • <temporary>: 這個標記意味著 MySQL 需要使用一個臨時表(可能在內存或磁盤上)來完成排序操作。這通常發生在 ORDER BY 的字段沒有可用索引時。
  • 實際執行: (actual time=8.306..8.431 rows=125 loops=1)
    • actual time: 從開始接收數據到排序完成并輸出最后一行,總共耗時約 8.431 毫秒。這是整個查詢的主要耗時部分。
    • rows=125: 排序了 125 行數據。

總結與性能分析

  1. 連接策略: 查詢使用了 Nested Loop Join。對于外層結果集不大(51行)的情況,這是一個合理的選擇。
  2. 外層掃描: 對 country 表進行了全表掃描。由于該表只有 239 行,這幾乎沒有性能影響。如果 country 表非常大,那么在 Continent 字段上建立索引將是首要的優化點。
  3. 內層查找: 對 city 表的查找使用了 CountryCode 索引,這是非常高效的。
  4. 排序: 查詢的最后一步是排序,并且使用了臨時表。這是因為結果集是動態生成的,無法利用現有索引來避免排序。這是查詢總耗時的主要來源。
  5. 優化器估算: 優化器在行數估算上存在一些偏差(如亞洲國家34 vs 51,每個國家的城市數18 vs 35),但這些偏差沒有導致選擇錯誤的執行計劃。
  6. 潛在優化: 如果要進一步優化,可以考慮在 city 表上創建一個復合索引 (CountryCode, Population)。這樣數據庫可以在索引層面就完成對 Population > 1000000 的過濾,減少從磁盤讀取的數據頁,可能會略微提升性能。

文章如有問題,請彥祖幫忙指正!感激不盡!


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

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

相關文章

Google I/O Extended :2025 Flutter 的現狀與未來

大家好&#xff0c;我是 Flutter GDE 郭樹煜&#xff0c;Github GSY 項目的維護人&#xff0c;今天主要分享的內容是「Flutter 的現狀與未來」&#xff0c;可能今天更多會是信息科普類型的內容&#xff0c;主要是分享關于 Flutter 的現狀與未來 現狀 其實 Flutter 從開源到現在…

軟考(軟件設計師)數據庫原理:事務管理,備份恢復,并發控制

數據庫事務管理與備份恢復 事務&#xff08;Transaction&#xff09; 是數據庫管理系統中執行的一個不可分割的工作單元&#xff0c;它包含一組 SQL 操作&#xff0c;這些操作要么全部成功執行&#xff0c;要么全部不執行。 事務的四大特性&#xff08;ACID&#xff09;&…

【牛客刷題】相遇

文章目錄 一、題目介紹1.1 題目描述1.2 輸入描述1.3 輸出描述1.4 示例二、解題思路2.1 核心算法設計2.2 性能優化關鍵2.3 算法流程圖三、解法實現3.1 解法一:基礎實現3.1.1 初級版本分析3.2 解法二:優化版本(推薦)3.2.1 優化版本分析一、題目介紹 1.1 題目描述 街道可以看…

uni-app 下拉搜索多選 支持自己創建數據

組件 /components/selectmul.vue <template><view class="multi-select-container"><view class="input-dropdown-container"><view class="" v-if="selectlist&&selectlist[0]"><text class=&qu…

nmon使用方法

安裝方法 方法1&#xff1a; 最簡單方法&#xff1a; #dnf install nom 驗證 執行命令&#xff1a; #nmon 方法2&#xff1a; 下載安裝包安裝&#xff0c;下載地址 官網&#xff1a;nmon and njmon | Site / Download 或者&#xff1a;https://sourceforge.net/project…

Google AI 剛剛開源 MCP 數據庫工具箱,讓 AI 代理安全高效地查詢數據庫

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

數學建模的一般步驟

歸納編程學習的感悟&#xff0c; 記錄奮斗路上的點滴&#xff0c; 希望能幫到一樣刻苦的你&#xff01; 如有不足歡迎指正&#xff01; 共同學習交流&#xff01; &#x1f30e;歡迎各位→點贊 &#x1f44d; 收藏? 留言?&#x1f4dd; 青春由磨礪而出彩&#xff0c;人生因奮…

【web安全】SQLMap 參數深度解析:--risk 與 --level 詳解

目錄 簡介 一、--risk 參數&#xff1a;測試風險控制 1. 基本定義 2. 各級別詳細對比 risk1 (默認) risk2 risk3 3. 使用建議 二、--level 參數&#xff1a;測試深度控制 1. 基本定義 2. 各級別詳細對比 level1 (默認) level2 level3 level4 level5 3. 技術實…

YOLO在自動駕駛交通標志識別中的應用與優化【附代碼】

文章目錄YOLO在自動駕駛交通標志識別中的應用與優化引言1. YOLO算法概述1.1 YOLO的核心思想1.2 YOLO的演進2. 交通標志識別的挑戰2.1 數據集特性2.2 性能指標要求3. YOLO模型優化策略3.1 數據增強改進3.2 注意力機制集成3.3 針對小目標的改進4. 完整實現示例4.1 模型訓練代碼4.…

開源鴻蒙(OpenHarmony)桌面版全面解析:架構適配、設備支持與開發實戰

摘要:深度剖析OpenHarmony 4.0+桌面版的技術演進,揭秘其在X86/國產芯片設備的落地實踐,附源碼獲取與開發板實戰指南 一、OpenHarmony桌面版架構突破 1.1 跨平臺內核適配 開源鴻蒙通過 多內核混合架構 實現全場景覆蓋: X86架構:集成Linux內核適配層(kernel/linux),支持…

【WEB】Polar靶場 11-15題 詳細筆記

目錄 十一.爆破 PHP的基本語法 變量與常量 數據類型 流程控制 函數 文件操作 數據庫交互 1.substr() 函數 2. intval() 函數 十二.XFF X-Forwarded-For&#xff08;簡稱XFF&#xff09; 十三.rce1 shell 命令分隔符 isset()函數 preg_match_all()函數 ${IFS}…

導診系統的科室和癥狀詞庫如何擴展?

要擴展導診系統的科室和癥狀詞庫&#xff0c;可以通過以下幾種方式實現&#xff1a;1. 直接擴展科室定義&#xff08;推薦&#xff09;在初始化代碼中直接添加新的科室及對應癥狀&#xff1a;# 擴展后的科室定義 depts [Department("內科", ["發熱", &quo…

通過Prompt生成互動式網頁HTML案例探索(二)

之前提到了一些【通過Claude 生成圖片的prompt集錦&#xff08;一&#xff09;】&#xff0c;本篇沿著試著用prompt生成互動式網頁 文章目錄 1 什么是互動式網頁&#xff1f;1.1 一個&#x1f330;1.1 核心能力列舉1.3 部署方式 2 猜測秘塔AI搜索生成HTML的Prompt3 mozi大佬&am…

暑假讀書筆記第四天

今日文章&#xff1a; 小林coding&#xff1a;什么是軟中斷&#xff1f; 目錄軟中斷軟中斷概述軟中斷類型如何定位軟中斷 CPU 使用率過高的問題&#xff1f;其他: 往期打卡 軟中斷 中斷是系統用來響應硬件設備請求的一種機制&#xff0c;操作系統收到硬件的中斷請求&#xf…

跨平臺的ARM 和 x86 Docker 鏡像:匯編語言實驗環境搭建

一、安裝和配置 Docker 1.安裝 Docker 官網鏈接&#xff1a;https://www.docker.com/ 以Debian(Ubuntu)系統為例: #安裝依賴包 sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release#添加 Docker 官方 GPG 密鑰 sudo mkdir -p /etc/apt/keyr…

【前端知識】HTML頁面渲染:底層原理與技術實現剖析

HTML頁面渲染&#xff1a;底層原理與技術實現剖析HTML頁面渲染&#xff1a;底層原理與技術實現剖析渲染引擎的核心工作流程深度解析渲染關鍵階段1. 解析與構建DOM&#xff08;Document Object Model&#xff09;2. 構建CSSOM&#xff08;CSS Object Model&#xff09;3. 渲染樹…

Catmull-Rom平滑多段線在奇異點處的扭曲問題(1)

Catmull-Rom在奇異點處的扭曲問題 引言 在計算機圖形學和動畫中&#xff0c;我們經常需要在已知點之間創建平滑的過渡。Catmull-Rom樣條是一種流行的插值方法&#xff0c;它以簡單直觀的方式生成經過所有控制點的平滑曲線。本文將深入探討Catmull-Rom插值的原理、實現和應用。…

SX8652IWLTRT Semtech升特超低功耗觸控芯片 12通道+I2C接口 重新定義人機交互!

SX8652IWLTRT&#xff08;Semtech&#xff09;產品解析與推廣文案一、產品定位SX8652IWLTRT是Semtech&#xff08;升特半導體&#xff09;推出的低功耗電容式觸摸控制器&#xff0c;采用IC接口&#xff0c;專為便攜式設備和小家電的觸摸交互設計&#xff0c;支持多點觸控和手勢…

第02章 MySQL環境搭建

1.MySQL的卸載 步驟1&#xff1a;停止MySQL服務 在卸載之前&#xff0c;先停止MySQL8.0的服務。按鍵盤上的“Ctrl Alt Delete”組合鍵&#xff0c;打開“任務管理器”對話框&#xff0c;可以在“服務”列表找到“MySQL8.0”的服務&#xff0c;如果現在“正在運行”狀態&#…

實戰Linux進程狀態觀察:R、S、D、T、Z狀態詳解與實驗模擬

前言 在Linux系統中&#xff0c;進程狀態是系統管理和性能調優的核心知識。一個進程從誕生到終止&#xff0c;會經歷運行&#xff08;R&#xff09;、可中斷睡眠&#xff08;S&#xff09;、不可中斷睡眠&#xff08;D&#xff09;、停止&#xff08;T&#xff09;、僵尸&#…