91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL 5.7Explain執行計劃

發布時間:2021-01-08 13:50:52 來源:億速云 閱讀:129 作者:小新 欄目:MySQL數據庫

小編給大家分享一下MySQL 5.7Explain執行計劃,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

目錄

  • 1. 介紹

  • 2. Explain 結果列詳解


    • 2.1 id

    • 2.2 select_type

    • 2.3 table

    • 2.4 partitions

    • 2.5 type(非常重要)

    • 2.6 possible_keys

    • 2.7 key

    • 2.8 key_len

    • 2.9 ref

    • 3.10 rows

    • 2.11 filtered

    • 2.12 Extra

【注】

  • 當前系統環境: MySQL 5.7,其他版本略有不同,后期會抽時間單獨說明。

  • 只介紹常見的場景,其他少見的場景暫不研究,如有需要可以去官方文檔中查找。

  • 非入門,需要對 MySQL 的底層數據結構 B+ 樹有一定的了解。

文檔參考:
MySQL 官方 Explain 文檔

1. 介紹

使用 EXPLAIN 關鍵字可以模擬優化器執行 SQL 語句,并分析查詢語句的性能瓶頸。

2. Explain 結果列詳解

2.1 id

  • id 列的編號是 select 的序列號,一般有幾個 select 就有幾個 id(聯表查詢會有重復的 id),并且 id 的順序是按 select 出現的順序增長的。

  • id 越大則表示執行的優先級越高,id 相同(一般出現在聯表查詢)則從上往下執行,idNULL 最后執行。

2.2 select_type

select_type 表示對應行是簡單的還是復雜的查詢。常見的值有:

  • simple:簡單查詢,查詢不包含子查詢和union。

  • primary:復雜查詢中最外層的 select 。

  • subquery:包含在 select 中的子查詢(不在 from 子句中)

  • derived:包含在 form 子句中的子查詢,MySQL 會將結果放在一個臨時表中,也稱為派生表。

  • union:在 union 中的第二個或之后的 select。

【注】在 MySQL 5.7 中,會對衍生表進行合并優化,如果要直觀的查看 select_type 的值,需要臨時關閉該功能(默認是打開的),下面的介紹中凡是涉及到衍生表的都需要該操作

# 關閉衍生表的合并優化(只對該會話有效)set session optimizer_switch='derived_merge=off'; # 打開衍生表的合并優化(只對該會話有效)set session optimizer_switch='derived_merge=on';

2.3 table

對應行查詢的表。

【注】

  • from 子句中有子查詢時,table 列為是 <derivenN> 的格式,表示這一行的執行的是 id = N 行的查詢。

  • 當有 union 時,table 的數據為 <union M,N> 的格式,M 和 N 表示參與 unionselectid

2.4 partitions

未完待續。。。

2.5 type(非常重要)

  • type 表示這行查詢的關聯類型(訪問類型,或查詢類型),通過該值可以了解該行查詢數據記錄的大概范圍。

  • 常見的值依次從最優到最差分別為:system > const > eq_ref > ref > range > index > ALL;一般我們要保證效率的話,要優化我們的語句至少使其達到 range 級別,如果可能的話做好優化到 refrange 一般用于范圍查找,所以換句話說除了范圍查找,其他的查詢語句我們最好是優化到 ref 級別。

常見值說明

  • NULL : 表示 MySQL 能夠在優化階段分解查詢語句,在執行階段不用訪問表和索引。

  • system / const: MySQL 能對某個查詢部分進行優化并將其轉化成一個常量(可以通過 show warnings 查看優化的結果),主要是查詢主鍵(Primary Key)或唯一鍵索引(Unique Key)對應的記錄,因為不存在重復,所以最多只能查詢出一條記錄,所以速度比較快。systemconst 的特例,當臨時表里只有一條記錄時為 system

    # 表里有一個主鍵id為1的記錄 - constexplain select * from student where id = 1# 派生表里面只有一條記錄 - systemexplain select * from (select * from student where id = 1) tmp# 注: 如果查詢的列中有 text 類型,那么在這里 type 會變為 ALL ,# 因為無法使用內存臨時表,只能在磁盤上創建臨時表,所以性能上會有所損耗,效果等同于全表查詢 ALL。
  • req_ref:當主鍵或唯一鍵索引的相關列并聯接使用時(聯表查詢),最多匹配一條符合條件的記錄。這是除了 const之外的最好的聯接類型,簡單的 select 查詢不會出現 req_ref,更多出現在聯表查詢。

    # 雖然返回結果中有多條記錄,但是在查詢中一個學生id只對應一個班級,所以查詢班級的時候為 req_ref,# 但是查詢 student 的時候是 ALL,全表查詢explain select * from student left join banji on student.id = banji.student_id

【注】在查詢的過程中的返回結果如下:
MySQL 5.7Explain執行計劃
當聯接表查詢時候會看作是一條查詢 SQL,所以它們對應的 id 是一樣的,當 id 都是一樣的時候,按照從上到下的順序依次執行,這里是先查詢班級所有的學生(全表查詢 ALL),然后根據學生id查找出學生對應的班級信息(req_ref)。

  • ref:當使用普通索引(Normal)或者是聯合索引的部分前綴時,索引要和某個值進行比較,可能會找到多個符合條件的記錄行,從輔助索引的根節點開始對比并找到相應的記錄。

    # 簡單的 select 查詢,name 是普通索引(Normal Index)explain select * from student where name = '張三';# 簡單 select 查詢,banji_id (第一個) 和 student_id (第二個) 的聯合索引EXPLAIN SELECT * FROM banji_student WHERE banji_student.banji_id = 3# 關聯表查詢# 包含 banji 表,banji_student 是班級與學生的關系表# 關系表中有 banji_id (第一個) 和 student_id (第二個) 的聯合索引 idx_banji_stu_id 索引,# 以下查詢只用到了聯合索引的 banji_id (第一個)explain select * from banji_id from banji left join banji_student 
    	on banji.id = banji_student.banji_id
  • range:范圍掃描,通常出現在 in,between,>,<,>= 等操作中,使用一個索引來檢索給定范圍的行。

    # 查詢 id 大于 1 的學生信息explain select * from student where id > 2;
  • index

    # student 表只有id主鍵,name 普通索引select * from student;# 這個時候會走 name 索引# 因為 name 是普通索引,所以如果加 where 的話可以達到 ref 級別select * from student where name = 'Ana'

    覆蓋索引定義:覆蓋索引一般針對于輔助索引,并不是真正的索引,只是索引查找的一種方式。如果 select 查詢的字段都在輔助索引樹中全部拿到,這種情況一般是使用了覆蓋索引,不需要通過輔助索引樹找到主鍵,再通過主鍵主鍵索引樹里獲取其它字段值。

    • 掃描全索引就能拿到結果,一般是掃描某個二級索引輔助索引,除了主鍵之外的索引)。這種索引不會從主鍵索引樹根節點開始查找,而是直接對二級索引的葉子節點遍歷和掃描,從而查找出相應的記錄行,速度比較慢;

    • 這種查詢方式一般為使用覆蓋索引,查詢所需的所有結果集在二級索引主鍵索引中都有的情況下,由于二級索引一般比較小(因為二級索引非聚集的,其葉子節點是存放的主鍵索引相應的地址,而主鍵索引是聚集的,其葉子節點存放的是完整的數據集),所以優先走二級索引,這種情況通常比 ALL 快一些。

    • 在某些情況下,如果表的列數特別多,這個時候通過輔助索引查詢的性能就不如直接使用主鍵索引效率高(如果查詢了輔助索引的話,還會返回到主鍵索引中進行查找更多的字段,也就是回表查詢,當然在某些情況下使用回表查詢的性能也會比只使用主鍵索引的性能高),這個時候會走主鍵索引,這種情況也比 ALL 快。

  • ALL:全表掃描,掃描主鍵(聚簇、聚集)索引樹的所有葉子節點,通常這種情況下要根據業務場景來增加其他索引進行優化。

    # id 為主鍵的 student 表,沒有其他索引,該查詢為 ALL.select * from student

2.6 possible_keys

possible_keys 主要顯示查詢可能用到哪些索引來查找,只是可能會使用,并不代表一定會使用。

常見值說明:

  • NULL: 沒有相關索引,如果是 NULL 的話,可以考慮在 where 子句中創建一個適當的索引來提高查詢性能,然后繼續用 explain 查看其效果;也有可能出現 possible_keysNULL,但是 key 有值,實際走了索引。

  • 有列值:如果顯示表中的某列,則表示可能會走這一列對應列值的索引;如果 possible_keys 有值,但是 key 顯示 NULL這種情況一般存在于表中數據量不大的情況,因為 MySQL 語句優化器認為索引對此查詢的幫助不大,從而選擇了全表查詢

2.7 key

  • key 表示 MySQL 實際采用哪個索引來優化對該表的查詢。

  • 如果沒有使用索引,則該列為 NULL,如果想強制 MySQL 使用或忽略 possible_keys 列中的索引,可以在查詢中使用 force indexignore index.

2.8 key_len

顯示了 MySQL 索引所使用的字節數,通過這個數值可以計算具體使用了索引中的哪些列(主要用于聯合索引的優化)。

【注】索引最大長度是 768 字節當字符串過長時MySQL 會做一個類似左前綴索引的處理,將前半部分的字符提取出來做索引。

示例:一個學生與班級的關系表:banji_student,存在使用 banji_idstudent_id 兩個列組合的聯合索引,并且每個索引 int 都是 4 字節,通過 key_len 值為 4 可以知道只使用了聯合索引的第一列:banji_id 來執行索引查找。

# 只使用了聯合索引的第一列select * from banji_student where banji_id = 2

key_len 的計算規則如下:

  • 字符串:常見的是 char(n)varchar(n),從 MySQL 5.0.3 之后,n 均表示字符數,而不是字節數,如果是 UTF-8,一個數字或字母占1個字節,一個漢字占3個字節。


    描述
    char(n)非漢字長度為 n,如果存放漢字長度為 3n 字節
    varchar(n)非漢字長度為 n+2,如果存放漢字長度為 3n+2 字節;因為 varchar 是可變長字符串,需要 2 字節來存儲字符串長度
  • 數值類型


    描述
    tinyint長度為 1 字節
    smallint長度為 2 字節
    int長度為 4 字節
    bigint長度為 8 字節
  • 時間類型


    描述
    date長度為 3 字節
    timestamp長度為 4 字節
    datetime長度為 8 字節
  • NULL

    如果字段允許設置為 NULL,則需要 1 字節來記錄是否為 NULLNot NULL 的列則不需要。

2.9 ref

顯示了在使用 key 列中實際的索引時,表查找時所用到的列名和常量;常見的為 const 常量或索引關聯查詢的字段(列)名

# 使用了常量 2,所以在查詢的時候 ref 為 constselect * from student where id = 2# 關聯表查詢# 包含 banji 表,banji_student 是班級與學生的關系表# 關系表中有 banji_id (第一個) 和 student_id (第二個) 的聯合索引 idx_banji_stu_id 索引# 這里的 ref 為 test.id ,也就是指的是 banji.idexplain select * from banji_id from banji left join banji_student 		on banji.id = banji_student.banji_id

3.10 rows

顯示預計查詢的結果數,并不是真正的結果集中的記錄(行)數,僅供參考。

2.11 filtered

未完待續。。。

2.12 Extra

這一列展示的是額外的信息,存在很多值,且在不同的場景下以及不同版本的 MySQL 所表示的意思也不同,只能是表示大概的意思并且僅做優化參考,這里只介紹常見的值。

  • Using index:使用覆蓋索引,在 type 相同的情況下, Extra 的值為 Using index 要比為 NULL 性能高。

    比如 banji 表,存在 id,name,create_time 列,存在 id 主鍵name 普通索引

    # 覆蓋索引,直接查詢 name 對應的索引樹就可以滿足 select 后面的查詢列select id,name from banji# 非覆蓋索引,雖然也走了索引,但是進行了回表查詢,以查詢出 create_time 字段。select * from banji where name = '二年級'
  • Using where:使用 where 關鍵字來查詢,并且對應的列沒有設置索引,對應的 keyNULL

    這種情況一般要對查詢的列添加相對應的索引來進行優化。

  • Using index condition:非覆蓋索引查詢并進行了回表,并且輔助索引使用了條件查詢語句(where 或其他)。

    比如 banji_student 關系表,存在 id,banji_id,student_id,create_time 列,存在 id 主鍵banji_id 與 student_id 的組合(聯合)索引

    # 進行了回表查詢,以查詢出 create_time 列,并且組合索引進行了范圍查找select * from banji_student where banji_id > 3
  • Using temporaryMySQL 需要創建創建一個臨時表來處理查詢,出現這種情況一般要添加索引進行優化處理。

    # 如果 name 沒有添加普通索引的話,則需要創建一個臨時表來進行去重,Extra 值為 Using temporary# 如果添加了索引,則會走 name 對應的索引樹,并且是覆蓋索引,Extra 值為 Using indexexplain select distinct name from student
  • Using filesort:使用外部排序而不是索引排序,當數據較小的時候采用的是內存排序,當數據量較大的時候會頻繁的訪問磁盤,并將排序后的數據寫入磁盤。

    # 如果 name 沒有添加普通索引的話,則需要創建一個臨時表來進行去重,Extra 值為 Using filesort# 如果添加了索引,則會走 name 對應的索引樹,并且是覆蓋索引,Extra 值為 Using indexexplain select name from student order by name
  • Select tables optimized away:使用聚合函數(例如 maxmin等)來訪問存在索引的字段時,只訪問索引樹中已排好序的葉子,節點性能很高。

    # 比如使用聚合函數 min 查詢最小的學生 id(主鍵)explain select min(id) from student

以上是“MySQL 5.7Explain執行計劃”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丘北县| 广西| 鄂温| 黄大仙区| 龙里县| 肇庆市| 新民市| 德格县| 磴口县| 鹤山市| 谢通门县| 永春县| 定日县| 玉树县| 巢湖市| 安化县| 宝兴县| 临漳县| 长治市| 滁州市| 金湖县| 芜湖市| 杭锦旗| 海宁市| 高碑店市| 北辰区| 西和县| 望谟县| 舟山市| 新源县| 固始县| 都兰县| 古丈县| 获嘉县| 静宁县| 安远县| 三原县| 库伦旗| 丹棱县| 东光县| 古田县|