mysql影片教學##欄位介紹Explain 執行計劃
目錄
- #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相同(一般出現在聯表查詢)則從上往下執行,
id為
NULL 最後執行。
2.2 select_type
#select_type
-
:簡單查詢,查詢不包含子查詢和union。simple
-
:複雜查詢中最外層的 select 。primary
-
:包含在select 中的子查詢(不在from 子句中)subquery
-
:包含在form 子句中的子查詢,MySQL 會將結果放在一個暫存表中,也稱為衍生表。derived
-
:在 union 中的第二個或之後的 select。union
【註】在
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表示參與
union的
select行
id 。
2.4 partitions
未完待續。 。 。2.5 type(非常重要)
-
#type
表示這行查詢的關聯類型(存取類型,或查詢類型),透過該值可以了解該行查詢資料記錄的大概範圍。 -
常見的值依序從最優到最差分別為:
system > const > eq_ref > ref > range > index > ALL;一般我們要保證效率的話,要優化我們的語句至少使其達到
range級別,如果可能的話做好優化到
ref;
range一般用於範圍查找,所以換句話說除了範圍查找,其他的查詢語句我們最好是優化到
ref 層級。
常見值說明
:-
能夠在最佳化階段分解查詢語句,在執行階段不用存取表和索引。#NULL
: 表示
MySQL -
。 ###system / const
: MySQL 能對某個查詢部分進行最佳化並將其轉換成常數(可以透過
show warnings查看最佳化的結果),主要是查詢主鍵(
Primary Key)或唯一鍵索引(
Unique Key)對應的記錄,因為不存在重複,所以最多只能查詢出一筆記錄,所以速度比較快。
system是
const的特例,當臨時表裡只有一筆記錄時為
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
【注】在查询的过程中的返回结果如下:
当联接表查询时候会看作是一条查询 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_keys
为NULL
,但是key
有值,实际走了索引。 - 有列值:如果显示表中的某列,则表示可能会走这一列对应列值的索引;如果
possible_keys
有值,但是key
显示NULL
,这种情况一般存在于表中数据量不大的情况,因为MySQL
语句优化器认为索引对此查询的帮助不大,从而选择了全表查询
。
2.7 key
-
key
表示MySQL
实际采用哪个索引来优化对该表的查询。 - 如果没有使用索引,则该列为
NULL
,如果想强制MySQL
使用或忽略possible_keys
列中的索引,可以在查询中使用force index
或ignore index
.
2.8 key_len
显示了 MySQL
索引所使用的字节数
,通过这个数值可以计算具体使用了索引中的哪些列(主要用于联合索引的优化)。
【注】索引最大长度是 768 字节
,当字符串过长时,MySQL
会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。
示例:一个学生与班级的关系表:
banji_student
,存在使用banji_id
与student_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
字节来记录是否为NULL
;Not 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
关键字来查询,并且对应的列没有设置索引,对应的key
为NULL
。这种情况一般要对查询的列添加相对应的索引来进行优化。
-
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 temporary
:MySQL
需要创建创建一个临时表来处理查询,出现这种情况一般要添加索引进行优化处理。# 如果 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
:使用聚合函数
(例如max
、min
等)来访问存在索引的字段时,只访问索引树中已排好序的叶子,节点性能很高。# 比如使用聚合函数 min 查询最小的学生 id(主键)explain select min(id) from student
以上是詳解 MySQL 5.7 最佳化:Explain 執行計劃的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

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

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

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

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

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

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

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


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

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

SublimeText3 Linux新版
SublimeText3 Linux最新版

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

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

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