搜尋
首頁資料庫mysql教程詳解 MySQL 5.7 最佳化:Explain 執行計劃

詳解 MySQL 5.7 最佳化:Explain 執行計劃

Jan 07, 2021 am 09:24 AM
explainmysql執行計劃

mysql影片教學##欄位介紹Explain 執行計劃

詳解 MySQL 5.7 最佳化:Explain 執行計劃

推薦(免費):mysql影片教學

目錄

    #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
    • 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 列為是 的格式,表示這一行的執行的是id ​​= N
  • 行的查詢。
  • 當有union 時,table 的資料為 的格式,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.7 最佳化:Explain 執行計劃
当联接表查询时候会看作是一条查询 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

    • 扫描全索引就能拿到结果,一般是扫描某个二级索引辅助索引,除了主键之外的索引)。这种索引不会从主键索引树根节点开始查找,而是直接对二级索引的叶子节点遍历和扫描,从而查找出相应的记录行,速度比较慢;
    • 这种查询方式一般为使用覆盖索引,查询所需的所有结果集在二级索引主键索引中都有的情况下,由于二级索引一般比较小(因为二级索引非聚集的,其叶子节点是存放的主键索引相应的地址,而主键索引是聚集的,其叶子节点存放的是完整的数据集),所以优先走二级索引,这种情况通常比 ALL 快一些。
    • 在某些情况下,如果表的列数特别多,这个时候通过辅助索引查询的性能就不如直接使用主键索引效率高(如果查询了辅助索引的话,还会返回到主键索引中进行查找更多的字段,也就是回表查询,当然在某些情况下使用回表查询的性能也会比只使用主键索引的性能高),这个时候会走主键索引,这种情况也比 ALL 快。
    # student 表只有id主键,name 普通索引select * from student;# 这个时候会走 name 索引# 因为 name 是普通索引,所以如果加 where 的话可以达到 ref 级别select * from student where name = 'Ana'

    覆盖索引定义:覆盖索引一般针对于辅助索引,并不是真正的索引,只是索引查找的一种方式。如果 select 查询的字段都在辅助索引树中全部拿到,这种情况一般是使用了覆盖索引,不需要通过辅助索引树找到主键,再通过主键主键索引树里获取其它字段值。

  • 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.7 最佳化:Explain 執行計劃的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
MySQL的許可與其他數據庫系統相比如何?MySQL的許可與其他數據庫系統相比如何?Apr 25, 2025 am 12:26 AM

MySQL使用的是GPL許可證。 1)GPL許可證允許自由使用、修改和分發MySQL,但修改後的分發需遵循GPL。 2)商業許可證可避免公開修改,適合需要保密的商業應用。

您什麼時候選擇InnoDB而不是Myisam,反之亦然?您什麼時候選擇InnoDB而不是Myisam,反之亦然?Apr 25, 2025 am 12:22 AM

選擇InnoDB而不是MyISAM的情況包括:1)需要事務支持,2)高並發環境,3)需要高數據一致性;反之,選擇MyISAM的情況包括:1)主要是讀操作,2)不需要事務支持。 InnoDB適合需要高數據一致性和事務處理的應用,如電商平台,而MyISAM適合讀密集型且無需事務的應用,如博客系統。

在MySQL中解釋外鍵的目的。在MySQL中解釋外鍵的目的。Apr 25, 2025 am 12:17 AM

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

MySQL中有哪些不同類型的索引?MySQL中有哪些不同類型的索引?Apr 25, 2025 am 12:12 AM

MySQL中有四種主要的索引類型:B-Tree索引、哈希索引、全文索引和空間索引。 1.B-Tree索引適用於範圍查詢、排序和分組,適合在employees表的name列上創建。 2.哈希索引適用於等值查詢,適合在MEMORY存儲引擎的hash_table表的id列上創建。 3.全文索引用於文本搜索,適合在articles表的content列上創建。 4.空間索引用於地理空間查詢,適合在locations表的geom列上創建。

您如何在MySQL中創建索引?您如何在MySQL中創建索引?Apr 25, 2025 am 12:06 AM

toCreateAnIndexinMysql,usethecReateIndexStatement.1)forasingLecolumn,使用“ createIndexIdx_lastNameEnemployees(lastName); 2)foracompositeIndex,使用“ createIndexIndexIndexIndexIndexDx_nameOmplayees(lastName,firstName,firstName);” 3)forauniqe instex,creationexexexexex,

MySQL與Sqlite有何不同?MySQL與Sqlite有何不同?Apr 24, 2025 am 12:12 AM

MySQL和SQLite的主要區別在於設計理念和使用場景:1.MySQL適用於大型應用和企業級解決方案,支持高性能和高並發;2.SQLite適合移動應用和桌面軟件,輕量級且易於嵌入。

MySQL中的索引是什麼?它們如何提高性能?MySQL中的索引是什麼?它們如何提高性能?Apr 24, 2025 am 12:09 AM

MySQL中的索引是數據庫表中一列或多列的有序結構,用於加速數據檢索。 1)索引通過減少掃描數據量提升查詢速度。 2)B-Tree索引利用平衡樹結構,適合範圍查詢和排序。 3)創建索引使用CREATEINDEX語句,如CREATEINDEXidx_customer_idONorders(customer_id)。 4)複合索引可優化多列查詢,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。 5)使用EXPLAIN分析查詢計劃,避

說明如何使用MySQL中的交易來確保數據一致性。說明如何使用MySQL中的交易來確保數據一致性。Apr 24, 2025 am 12:09 AM

在MySQL中使用事務可以確保數據一致性。 1)通過STARTTRANSACTION開始事務,執行SQL操作後用COMMIT提交或ROLLBACK回滾。 2)使用SAVEPOINT可以設置保存點,允許部分回滾。 3)性能優化建議包括縮短事務時間、避免大規模查詢和合理使用隔離級別。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。