MySql 執行計劃

来源:https://www.cnblogs.com/liyasong/archive/2018/09/10/mysql_zhixingjihua.html
-Advertisement-
Play Games

mysql執行計劃是sql語句經過查詢優化器後,查詢優化器會根據用戶的sql語句所包含的欄位和內容數量等統計信息,選擇出一個執行效率最優(mysql系統認為最優)的執行計劃,然後根據執行計劃,調用存儲引擎提供的介面,獲取數據。 但是,在mysql執行的時候,到底使用了一個什麼樣的執行計劃,有沒有用到 ...


  mysql執行計劃是sql語句經過查詢優化器後,查詢優化器會根據用戶的sql語句所包含的欄位和內容數量等統計信息,選擇出一個執行效率最優(mysql系統認為最優)的執行計劃,然後根據執行計劃,調用存儲引擎提供的介面,獲取數據。

  但是,在mysql執行的時候,到底使用了一個什麼樣的執行計劃,有沒有用到索引。當數據規模比較大的時候,sql執行的時候,執行計劃不同,會直接影響sql的執行速度。這個時候,就需要對sql語句執行進行調試。

  mysql我們在調試sql語句的時候,不會像我們寫java或者其他語言代碼那樣通過打斷點的方式進行代碼調試。這個時候,我們就需要通過查看執行計劃來調試我們的sql了。Mysql通過EXPLAIN來查看執行計劃,我們寫sql語句的時候,在語句之前加一個EXPLAIN就可以了。EXPLAIN可以用在SELECT、DELETE、INSERT、PEPLACE以及UPDATE等語句中,如:

1 EXPLAIN SELECT
2     *
3 FROM
4     school
5 WHERE
6     school_nick = '縣第一小學'
EXPLAIN SQL

  執行後,結果如下:

  這裡介紹下每個欄位以及每個欄位的含義:

  id

  id是執行計劃的標識符,是SELECT 查詢的序號。如果結果集會跟其他表的結果用UNION關鍵字相結合,那麼id可能為空。

  id是否為空,對執行計劃的影響不大,如果有興趣可以看另外一篇博客:mysql執行計劃id為空—UNION關鍵字,這裡不再贅述。

  select_type

  select_type表示sql語句查詢的類型。具體表示如下表:

select_type的值           含義
SIMPLE 簡單的select查詢,沒有使用關聯和子查詢。
PRIMARY 最外層select,包含子查詢的時候,最外層的查詢
UNION 在一個UNION查詢中,第二次或以後的子查詢操作
DEPENDENT UNION 在一個UNION查詢中,第二次子查詢或以後的SELECT查詢的時候需要依賴外部的查詢                          
UNION RESULT UNION的返回結果集
SUBQUERY 子查詢語句的第一個select語句
DEPENDENT SUBQUERY                                  依賴外部查詢的第一個子查詢
DERIVED 派生表——該臨時表是從子查詢派生出來的,位於form中的子查詢
MATERIALIZED 物化子查詢(不確定啥意思,以後研究後再回來補充,或者大神指教)
UNCACHEABLE SUBQUERY      無法緩存結果的子查詢,必須為外部查詢的每一行重新計算
UNCACHEABLE UNION UNION中的第二個或以後的不可緩存的子查詢。

  table

  輸出行引用的表的名稱。一般為表格名稱或別名,也可能為如下值:

  1.UNION的並集結果集。

  2.derivedN當前行指向派生結果集。可能是一個派生表,例如來自FROM子句的結果集。

  3.subqueryN 當前行指向一個子查詢的結果集。

  type

  連接類型。該列輸出表示如何連接表。下麵的類型表示從最好的到最壞的類型

  1.system 該表只有一行(=系統表)。這是const連接類型的特例 。

  2.const 最多只有一行匹配,在查詢開始的時候,計算出常量對應的地址,直接訪問,例如:select * from test where  name ='zhang' 當name是唯一索引的時候,就有可能出現const。const非常快,因為它只讀一次。

  3.eq_ref 除了 system和 const類型之外,這是最好的連接類型。當兩個表聯查時使用索引的所有部分(針對的是組合索引),且索引是 主鍵或唯一索引時使用它。使用“=”運算符來進行索引列的比較。

  4.ref 非唯一索引掃描,返回某個匹配值的所有行。常用語非唯一索引。這裡對於eq_ref 和ref不熟悉的同學,可以看以下代碼:

  
 1 -- 給test表的name欄位加唯一索引,test2 的job 行添加非唯一索引。
 2 -- 這個代碼執行後,首先執行test2 的查詢,查出job = ‘teacher’ 的所有集合。
 3 -- 所以test2 的typ是ref 表示的是匹配job = ‘teacher’ 的一個結果集。
 4 -- 然後從結果集中取出name的集合,去匹配test1.name的結果。因為test1.name是唯一索引,所以一個name最多匹配到一條記錄,所以test的type是ref
 5 EXPLAIN SELECT
 6     *
 7 FROM
 8     test,
 9     test2
10 WHERE
11     test. NAME = test2. NAME
12 AND test2.job = '33'
test ref and eq_ref

 

  執行結果如下圖:

  

  5.fulltext 使用fulltext 索引進行查詢。

  6.ref_or_null 這種鏈接類型類似於ref,但是,除了ref之外,還對包含null的值進行了搜索。常用於解析子查詢。代碼示例如下:

1 SELECT * FROM ref_table
2   WHERE key_column=expr OR key_column IS NULL;
ref_or_null

  7.index_merge 這個鏈接類型表示使用索引合併優化。輸出內容包含在索引列表中。

  8.unique_subquery 索引查找,替換子查詢,以提高效率。

value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery

  9. index_subquery 類似於unique_subquery 但是替換in子查詢,適用於非唯一索引,代碼: value IN (SELECT key_column FROM single_table WHERE some_expr) 

  10.range 掃描部分索引,對索引的掃描從某一點開始,返回的是某個索引區域的值。常見的有基於索引的 < ,> 等的查詢。

  11. index 掃描全部索引,對索引進行整體掃描。

  12.all 全表掃描,最慢的查詢 。應該避免

  possible_keys

  可能使用的key,指出當前查詢涉及到的行都含有那些索引。如果有索引就會列出,但是不一定會被使用。

  key

  實際使用的索引。如果沒有使用索引,顯示null。

  key_len

  表中對應的索引最大可能長度。可以通過設置索引長度改變該值。例如:一個varchar(255)的索引長度為255,可是我們使用不到那麼長,我們可以取字元串的前五位作為索引。這時key_len 就是5.這裡關於索引值的長度的選取規則,以後有機會再寫一篇博客詳細介紹。

  ref

  哪些欄位和key一起被使用。沒用過。

  rows

  受影響的行數。不是特別精確的。

  Extra

  解釋額外的信息。包含mysql對於query優化的時候的一些附加信息。非常有用。可能出現的結果如下:

  • const row not found 該表為空
  • Deleting all rows   表格內數據被標記刪除,正在刪除中(某些存儲引擎支持一種方法,以簡單快捷的方式刪除所有行,這時查詢就會出現這個提示)
  • Distinct  MySQL正在尋找不同的值,因此它在找到第一個匹配行後停止為當前行組合搜索更多行。
  • FirstMatch(tbl_name) 半連接FirstMatch連接快捷方式策略用於tbl_name
  • Full scan on NULL key當優化程式無法使用索引查找訪問方法時,子查詢優化將作為回退策略發生。
  • Impossible HAVINGHAVING子句始終為false,無法選擇任何行。
  • Impossible WHERE WHERE子句始終為false,無法選擇任何行。
  • Impossible WHERE noticed after reading const tables MySQL已經讀取了所有 const(和 system)表,並註意到該WHERE子句始終為false。
  • No matching min/max row 沒有行滿足查詢的條件的行
  • no matching row in const table  對於具有連接的查詢,有一個空表或沒有滿足唯一索引條件的行的表。
  • No matching rows after partition pruning  對於DELETE或 UPDATE,優化器在分區修剪後發現沒有刪除或更新的內容。
  • No tables used 查詢沒有FROM子句
  • Not exists 查詢的內容不存在 
  • Plan isn't ready yet 優化程式尚未完成為在命名連接中執行的語句創建執行計劃時, 會出現此值
  • Range checked for each record MySQL發現沒有好的索引可以使用,但發現在前面的表的列值可能會使用某些索引。
  • Recursive  遞歸
  • Skip_open_table, Open_frm_only, Open_full_table  
    • Skip_open_table:表文件不需要打開。該信息已從數據字典中獲得。

    • Open_frm_only:只需要讀取表信息的數據字典。

    • Open_full_table:未優化的信息查找。必須從數據字典中讀取表信息並讀取表文件。

  • unique row not found  對於查詢,沒有行滿足 索引或表的條件。
  • Using filesort  使用文件排序。MySQL必須執行額外的傳遞以找出如何按排序順序檢索行。排序是通過根據連接類型遍歷所有行並將排序鍵和指針存儲到與該WHERE子句匹配的所有行的行來完成的然後對鍵進行排序,並按排序順序檢索行
  • Using index 僅使用索引樹中的信息從表中檢索列信息,而不必另外尋找讀取實際行。當查詢僅使用屬於單個索引的列時,可以使用此策略。
  • Using index condition  通過首先訪問索引,確定是否可以讀取完整的表行。
  • Using index for group-by  使用索引分組。表示MySQL找到了一個索引,可用於檢索GROUP BY或 DISTINCT查詢的所有列,而無需對實際表進行任何額外的磁碟訪問。此外,索引以最有效的方式使用,因此對於每個組,只讀取少數索引條目。
  • Using index for skip scan  使用索引跳過掃描範圍
  • Using join buffer  將表數據讀入緩存,然後從緩存中讀數據來執行操作。
  • Using MRR 使用多範圍讀取優化策略讀取表。
  • Using temporary 使用臨時表,MySQL需要創建一個臨時表來保存結果。如果查詢包含以不同方式列出列的GROUP BY和 ORDER BY子句,則通常會發生這種情況
  • Using where  使用上了where限制,表示MySQL伺服器在存儲引擎受到記錄後進行“後過濾”(Post-filter),如果查詢未能使用索引,Using where的作用只是提醒我們MySQL將用where子句來過濾結果集。
  • Zero limit  查詢有一個LIMIT 0子句,不能選擇任何行。
  • Only index  這意味著信息只用索引樹中的信息檢索出的,這比掃描整個表要快。 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Preface When I was compiling the sysbench just now,I encountered some failures in the precedure.I'll show the issue and workaround below. Issues 1. Ex ...
  • 一: redis資料庫安裝 系統環境:linux系統(centos/redhat):Red Hat Enterprise Linux Server release 6.8 (Santiago) redis版本:4.0.11 說明:由於本次採用的是源碼安裝(適用於在生產環境中無法訪問外網的情況),所以 ...
  • 索引設計基礎知識 索引是與表或視圖關聯的磁碟上結構,可以加快從表或視圖中檢索行的速度。 索引包含由表或視圖中的一列或多列生成的鍵。 這些鍵存儲在一個結構(B 樹)中,使 SQL Server 可以快速高效地找到與鍵值關聯的行。 為資料庫及其工作負荷選擇正確的索引是一項需要在查詢速度與更新所需開銷之間 ...
  • 一、 選擇適合自己的Linux發行版 談到linux的發行版別,太多了,可能誰也不能給出一個準確的數字,但是有一點是能夠必定的,linux正在變得越來越盛行, 面臨這麼多的Linux 發行版,打算從別的體系轉到linux體系來的初學者可能會感到迷惑,即便是忠誠的 Linux 用戶也沒有時刻和精力去挨 ...
  • 介紹UNion 關鍵字,順便介紹 什麼情況下mysql執行計劃的id為null ...
  • Redis哨兵,它基於主從複製,主要作用是解決主節點故障恢復的自動化問題,進一步提高系統的高可用性。文章內容如下:首先介紹哨兵的作用和架構;然後講述哨兵系統的部署方法,以及通過客戶端訪問哨兵系統的方法;然後簡要說明哨兵實現的基本原理;最後給出關於哨兵實踐的一些建議。 ...
  • 在某些情況下,將讀請求發送給副本集的備份節點是合理的,例如,單個伺服器無法處理應用的讀壓力,就可以把查詢請求路由到可複製集中的多台伺服器上。現在絕大部分MongoDB驅動支持讀偏好設置(read preference;或翻譯為讀取首選項),用來告訴驅動從特定的節點讀取數據。 1 讀偏好選項 prim ...
  • 1、Mycat的分片 兩台資料庫伺服器: 192.168.80.11 192.168.80.4 操作系統版本環境:centos6.5 資料庫版本:5.6 mycat版本:1.4 release 資料庫:db1,db2,db3 說明:db1.db2 在192.168.80.11 伺服器上 ,db3在1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...