成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

一文帶你快速看懂 MySQL 執行計劃

一文帶你快速看懂 MySQL 執行計劃

程序員必備接口測試調試工具:立即使用
Apipost = Postman + Swagger + Mock + Jmeter
Api設計、調試、文檔、自動化測試工具
后端、前端、測試,同時在線協作,內容實時同步

通常查詢慢查詢SQL語句時會使用EXPLAIN命令來查看SQL語句的執行計劃,通過返回的信息,可以了解到Mysql優化器是如何執行SQL語句,通過分析可以幫助我們提供優化的思路。

1. Explain 作用

explain 命令主要用于查看 SQL 語句的執行計劃,該命令可以模擬優化器執行 SQL 查詢語句,可以幫助我們編寫和優化 SQL。那么 explain 具體可以提供哪些信息,幫助我們如何去優化 SQl 的呢?

  • 表的讀取順序

  • 數據讀取操作的操作類型

  • 哪些索引可以使用

  • 哪些索引被實際使用

  • 表之間的引用

  • 每張表有多少行被優化器查詢

2. Explain 如何使用

使用方式: explain + 待執行的sql

一文帶你快速看懂 MySQL 執行計劃

  explain 會返回一個待執行 SQL 的執行計劃列表,列表包含了 12 個字段,字段共同描述了 SQL 在執行計劃中將會采取何種方式執行。以下列表詳細描述了執行計劃表的字段含義:

字段名稱 描述
id 執行 select 語句查詢的序列號,決定表的讀取順序
select_type 查詢的類型,也就是數據讀取操作的操作類型
table 查詢的表名
partitions 表分區
type 訪問類型
possible_keys 可使用的索引。查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用到。如果這個字段為 null 但是字段 key 不為 null,這種情況就是在查找時沒有可以使用的二級索引樹,但是二級索引中包含了需要查詢的字段,于是就不再查找聚簇索引(聚簇索引比較大),轉而掃描這個二級索引樹(二級索引樹比較?。?,并且此時一般訪問類型 type 為 index,及掃描整棵索引樹。
key 實際掃描使用的索引。如果為 null,則沒有使用索引;查詢中若使用了覆蓋索引,則該索引僅出現在key列表中;
key_len 索引中使用的字節數??赏ㄟ^該列計算查詢中使用的索引的長度,在不損失精確性的情況下,長度越短越好;key_len 顯示的值為索引字段的最大可能長度,并非實際使用長度,即 key_len 是根據表定義計算而得,不是通過表內檢索出的;
ref 顯示索引的哪一列被使用了。如果可能的話,是一個常數,哪些列或常量別用于查找索引列上的值;
rows 根據表統計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數;
filtered 搜索條件過濾后剩余數據的百分比。
Extra 包含不適合在其它列中顯示但十分重要的額外信息

3. 關鍵字段分析

(1)id

執行 select 語句查詢的序列號,包含一組數字,表示查詢中執行 select 子句或操作表的順序,它有三種情況:

類型名稱 描述
id相同 執行順序由上至下
id不同 如果是子查詢,id 的序號會遞增,id 值越大優先級越高,越先被執行
id相同不同,同時存在 如果 id 相同,可以認為是一組,從上往下順序執行,在所有組中,id值越大,優先級越高,越先執行

(2)select_type

就是數據讀取操作的操作類型,他一共有以下幾種:

類型名稱 描述
simple 簡單的 select 查詢,查詢中不包含子查詢或者 union;
primary 查詢中若包含任何復雜的子查詢,最外層查詢則被標記;
subquery 在 select 或者 where 列表中包含了子查詢;
dependent subquery 子查詢中的第一個 SELECT, 取決于外面的查詢。 即子查詢依賴于外層查詢的結果。
derived 在 from 列表中包含的子查詢被標記為 DERIVED(衍生表),mysql 會遞歸執行這些子查詢,把結果放臨時表中;
union 若第二個 select 出現在 union 之后,則被標記為 union,若 union 包含在 from 子句的子查詢中,外層 select 將被標記為 DERIVED;
union result 從 union 表(即 union 合并的結果集)中獲取 select 查詢的結果;
meterialized 物化表,子查詢關聯查詢時,子查詢結果存儲在物化臨時表,然后根據臨時表中的數據去主表匹配。
dependent union UNION 中的第二個或后面的查詢語句,取決于外面的查詢

(3)table

顯示的查詢表名,如果查詢使用了別名,那么這里顯示的是別名,如果不涉及對數據表的操作,那么這顯示為 null,也可以是以下之一:

類型名稱 描述
<derivedN> 表示這個是臨時表,后邊的N就是執行計劃中的 id,表示結果來自于這個查詢產生。
<unionM,N> 與<derivedN>類似,也是一個臨時表,表示這個結果來自于 union 查詢的 id 為 M,N 的結果集。
<subqueryN> 該行是指與物化子查詢該行的結果 id 的值 N。

(4)partitions

查詢將匹配記錄的分區。該值NULL用于非分區表。

(5)type

依次從好到差:

system>const>eq_ref>ref>ref_or_null>range>index>ALL

除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一個索引。

我們自己創建一系列表來實驗下:

一文帶你快速看懂 MySQL 執行計劃

一文帶你快速看懂 MySQL 執行計劃

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;  -- ---------------------------- -- Table structure for goods -- ---------------------------- DROP TABLE IF EXISTS `goods`; CREATE TABLE `goods`  (   `id` int(11) NOT NULL,   `sn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,   PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;  -- ---------------------------- -- Records of goods -- ---------------------------- INSERT INTO `goods` VALUES (1, 'sn123456', '衣服');  -- ---------------------------- -- Table structure for sku -- ---------------------------- DROP TABLE IF EXISTS `sku`; CREATE TABLE `sku`  (   `id` int(11) NOT NULL,   `goods_id` int(11) NOT NULL,   `status` int(11) NOT NULL,   `deleted` int(11) NOT NULL,   `barcode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,   PRIMARY KEY (`id`) USING BTREE,   UNIQUE INDEX `index_2`(`name`) USING BTREE,   INDEX `index_1`(`goods_id`, `status`, `deleted`, `barcode`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;  -- ---------------------------- -- Records of sku -- ---------------------------- INSERT INTO `sku` VALUES (1, 1, 1, 0, 'kt123456', '黑色');  SET FOREIGN_KEY_CHECKS = 1;
登錄后復制

system

表只有一行記錄(等于系統表),這是 const 類型的特例,平時不會出現,這個也可忽略不計;

const

表示通過索引一次就找到了,const 用于比較 primary key 或者 unique 索引。因為只匹配一行記錄,所以很快。 如果將主鍵置于 where 列表中,mysql 就能將該查詢轉換成一個常量;

EXPLAIN SELECT * FROM sku WHERE id=1;復制代碼
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

eq_ref

唯一性索引掃描,對于每一個索引鍵,表中只有一條記錄與之匹配,常用于主鍵或唯一索引掃描;此類型通常出現在多表的 join 等值查詢,表示對于前表的每一個結果,都只能匹配到后表的一行結果,查詢效率較高。

EXPLAIN SELECT * FROM sku,goods WHERE sku.goods_id=goods.id;
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

ref

非唯一性索引掃描,返回匹配某個單獨值得所有行,本質上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,所以它應該屬于查找和掃描的混合體;

EXPLAIN SELECT * FROM sku WHERE goods_id=1;
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

ref_or_null

二級索引等值比較同時限定 is null 。

EXPLAIN SELECT * FROM sku WHERE name='123456' or name IS NULL;
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

range

只檢索給定范圍的行,使用一個索引來選擇行,key列顯示使用哪個索引,一般就是在你的 where 語句中出現了 between、<、>、in 等的查詢;這種范圍索引掃描比全表掃描要好,因為它只需要開始于索引的某一個點,結束于另一個點,不用掃描全部索引;

EXPLAIN SELECT * FROM sku WHERE id BETWEEN 1 and 10;
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

index

index 和 all 區別為 index 類型只遍歷索引樹,這通常比 all 快,因為索引文件通常比數據文件小;也就是說雖然 all 和 index 都是讀寫表,但 index 是從索引中讀取的,而 all 是從硬盤中讀的;

EXPLAIN SELECT barcode FROM sku WHERE deleted=0;
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

all

也就是全表掃描;

EXPLAIN SELECT * FROM sku WHERE deleted=0;
登錄后復制

一文帶你快速看懂 MySQL 執行計劃

(6)possible_keys

查詢可能使用到的索引都會在這里列出來。

(7)key

查詢真正使用到的索引,select_typeindex_merge時,這里可能出現兩個以上的索引,其他的select_type這里只會出現一個。

(8)key_len

key_len 表示該列計算查詢中使用的索引的長度。例如:SELECT * FROM table where age = 1 and name like 'xx',假設 age 是 int 類型且不可為 null;name 是 varchar(20) 類型且可以為 null,編碼為 utf8。若以這兩個字段為索引查詢,那么 key_len 的值為 4 + 3 * 20 + 2 + 1 = 67。具體計算規則如下表所示:

值類型 值名稱 描述
字符串 CHAR(n) n 字節長度
VARCHAR(n) 如果是 utf8 編碼,則是 3 n + 2字節;;如果是 utf8mb4 編碼,則是 4 n + 2 字節。
數值類型 TINYINT 1字節
SMALLINT 2字節
MEDIUMINT 3字節
INT 4字節
BIGINT 8字節
時間類型 DATE 3字節
TIMESTAMP 4字節
DATETIME 8字節
字段屬性 NULL 屬性 占用一個字節。如果一個字段是 NOT NULL 的, 則不占用。

(9)ref

如果是使用的常數等值查詢,這里會顯示const,如果是連接查詢,被驅動表的執行計劃這里會顯示驅動表的關聯字段,如果是條件使用了表達式或者函數,或者條件列發生了內部隱式轉換,這里可能顯示為func

(10)rows

這里是執行計劃中估算的掃描行數,不是精確值。

(11)filtered

使用explain extended時會出現這個列,5.7之后的版本默認就有這個字段,不需要使用explain extended了。這個字段表示存儲引擎返回的數據在server層過濾后,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數。

(12)Extra

這個列可以顯示的信息非常多,有幾十種,常用的有:

1、distinct:在select部分使用了distinct關鍵字

2、no tables used:不帶from字句的查詢或者From dual查詢。使用not in()形式子查詢或not exists()運算符的連接查詢,這種叫做反連接。即,一般連接查詢是先查詢內表,再查詢外表,反連接就是先查詢外表,再查詢內表。

3、using filesort:說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。mysql中無法利用索引完成的排序操作稱為“文件排序”。排序時無法使用到索引時,就會出現這個。常見于order by語句中,需要盡快優化

4、using index:查詢時不需要回表查詢,直接通過索引就可以獲取查詢的數據。

5、using join buffer(block nested loop),using join buffer(batched key accss)5.6.x之后的版本優化關聯查詢的BNLBKA特性。主要是減少內表的循環數量以及比較順序地掃描查詢。

6、using sort_union,using_union,using intersect,using sort_intersection:

  • using intersect:表示使用and的各個索引的條件時,該信息表示是從處理結果獲取交集
  • using union:表示使用or連接各個使用索引的條件時,該信息表示從處理結果獲取并集
  • using sort_union和using sort_intersection:與前面兩個對應的類似,只是他們是出現在用andor查詢信息量大時,先查詢主鍵,然后進行排序合并后,才能讀取記錄并返回。

7、using temporary:表示使用了臨時表存儲中間結果。臨時表可以是內存臨時表和磁盤臨時表,執行計劃中看不出來,需要查看status變量,used_tmp_table,used_tmp_disk_table才能看出來。常見于order by和分組查詢group by。group by一定要遵循所建索引的順序與個數。需要盡快優化

8、using where:表示存儲引擎返回的記錄并不是所有的都滿足查詢條件,需要在server層進行過濾。查詢條件中分為限制條件和檢查條件,5.6之前,存儲引擎只能根據限制條件掃描數據并返回,然后server層根據檢查條件進行過濾再返回真正符合查詢的數據。5.6.x之后支持ICP特性(index condition pushdown,索引下推),可以把檢查條件也下推到存儲引擎層,不符合檢查條件和限制條件的數據,直接不讀取,這樣就大大減少了存儲引擎掃描的記錄數量。extra列顯示using index condition

9、firstmatch(tb_name)5.6.x開始引入的優化子查詢的新特性之一,常見于where字句含有in()類型的子查詢。如果內表的數據量比較大,就可能出現這個

10、loosescan(m..n)5.6.x之后引入的優化子查詢的新特性之一,在in()類型的子查詢中,子查詢返回的可能有重復記錄時,就可能出現這個

4. Explain 主要關注點

總的來說,我們只需要關注結果中的幾列:

列名 備注
type 本次查詢表聯接類型,從這里可以看到本次查詢大概的效率
key 最終選擇的索引,如果沒有索引的話,本次查詢效率通常很差
key_len 本次查詢用于結果過濾的索引實際長度
rows 預計需要掃描的記錄數,預計需要掃描的記錄數越小越好
Extra 額外附加信息,主要確認是否出現Using filesortUsing temporary這兩種情況

再來看下Extra列中需要注意出現的幾種情況:

關鍵字 備注
Using filesort 將用外部排序而不是按照索引順序排列結果,數據較少時從內存排序,否則需要在磁盤完成排序,代價非常高,需要添加合適的索引
Using temporary 需要創建一個臨時表來存儲結果,這通常發生在對沒有索引的列進行GROUP BY時,或者ORDER BY里的列不都在索引里,需要添加合適的索引
Using index 表示MySQL使用覆蓋索引避免全表掃描,不需要再到表中進行二次查找數據,這是比較好的結果之一。注意不要和type中的index類型混淆
Using where 通常是進行了全表/全索引掃描后再用WHERE子句完成結果過濾,需要添加合適的索引
Impossible WHERE Where子句判斷的結果總是false而不能選擇任何數據,例如where 1=0,無需過多關注
Select tables optimized away 使用某些聚合函數來訪問存在索引的某個字段時,優化器會通過索引直接一次定位到所需要的數據行完成整個查詢,例如MIN()MAX(),這種也是比較好的結果之一

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
粉嫩小泬无遮挡久久久久久小说| 村长压在小雪身上耕耘视频| 欧美xxxxx久久短视频| 国产成人年无码AV片在线观看| 无码人妻丰满熟妇啪啪| 播放片高清MV在线观看| 亚洲AV无码成人片在线观看一区 | 国产色无码精品视频国产| 亚洲色大成网站WWW久久| 林静公交车被做到高C| 阿姨呀咿呀啊咿呀咿呀| 小雪被老汉各种姿势玩弄| 久久亚洲精品无码AⅤ电影| 办公室揉弄震动嗯~动态图| 亚洲AV无码精品色夜午夜网址| 久久综合伊人77777麻豆| 成年免费A级毛片免费看| 一本到高清视频在线观看丶 | 边做饭边被躁我和邻居的视频| 双乳被一左一右吃着的小说| 好男人日本社区WWW| 波多野结衣中文字幕免费视频| 亚洲AⅤ国产成人AV片妓女| 欧美日本国产VA高清CABAL| YW尤物无码点击进入| 亚洲AV无码一区二区三区DV| 末成年女A∨片一区二区| 国产精品乱码久久久久久小说 | 国产乱人伦AV在线无码| 中国WINDOWS野外| 少妇被粗大的猛烈进出96影院| 好爽好湿好硬好大免费视频| ACCA少女SDANVI| 亚洲AV无码专区在线观看下载| 欧洲人激情毛片无码视频| 精品久久一卡2卡三卡4卡分区| 国产精品亚洲АV无码播放| 人妻无码AⅤ中文字幕系列| 被群CAO的合不拢腿H纯肉视频 | 少妇亚洲XXXX| 国产偷国产偷精品高清尤物| CHINESE叫床国语VIDE| 在线无码VA中文字幕无码| 亚洲VA中文字幕无码久久不卡 | 亚洲Av无码一区二区三区大黄瓜| 日本大学学校AAAAA| 拍摄AV现场失控高潮数次| 男女猛烈激情XX00免费视频| 久久99热精品免费观看| 国产精品无码久久综合| 国产欧美日韩视频免费| 囯产精品一品二区三区| 被老头玩弄邻居人妻中文字幕| XXXXX18日本人HDXX| 布丁漫画土豪漫画入口页面| 95W乳液78WYW永久区域| 99精产国品一二三产品| 宝贝把腿张得大一点就不痛了| 变态拳头交视频一区二区| 亚洲A∨精品一区二区三区| 亚洲AV图片一亚洲AV| 无人免费观看视频在线观看| 玩弄中国白嫩少妇HD乱| 亚洲AV福利天堂一区二区三| 亚洲成A人一区二区三区| 亚洲国产精彩中文乱码AV| 亚洲精品成人久久久| 在线亚洲人成电影网站色WWW| 中日双语字幕高清在线观看 | chinese熟女老女人hd视频| Y111111国产精品久久久| 久久精品女人天堂AV麻| 你的婚礼免费观看完整版| 欧美狂野乱码一二三四区| 日本XX爽21护士| 午夜影视啪啪体验区入口| 亚洲熟妇无码八AV在线播放| 18禁黄网站禁片免费观看香港 | 国产一二三四区乱码免费| 久久ER99热精品一区二区| 女人扒开腿让男人狂桶30分钟| 日本高清视频WWW| 亚洲AV少妇熟女猛男| 岳今晚让我玩个够肥水一体探岳| YY111111少妇影院免费| 国产男女无遮挡猛进猛出| 久久亚洲精品成人AV无码网站| 人妻少妇看A偷人无码| 亚洲乱码av无码一区二区三区| 爆乳无码AV一区二区三区小说| 国产乱码1卡二卡3卡四卡| 毛很浓密超多黑毛| 无码免费一区二区三区| 一本一道波多野毛片结衣AV黑人| 欧美性BBBBBXXXXX4050免费看| 欧美亚洲综合另类色妞网| 亚洲AV纯肉无码精品动漫| JIZZJIZZ丝袜老师| 大黑大巴大战欧洲美女图片| 好硬好涨老师受不了了| 青青爽无码视频在线观看 | 国产成人毛片在线视频| 美女内射在线观看| 挽起裙子迈开腿坐上MBA| 被村长狂躁俩小时玉婷视频| 亚洲AV成人无码深夜高潮| 亚洲AV无码乱码一级毛片孕妇| 97精品依人久久久大香线蕉97| 国语对白露脸XXXXXX| 日本强伦姧人妻完视频正版| 亚洲乱码在线卡一卡二卡新区| 大又大又粗又硬又爽少妇毛片| 美女裸露双奶头尿口无遮挡网站 | 日本亚洲欧美一区二区麻豆| 在教室伦流澡到高潮H强圩电影 | 日产乱码一二三区别免费下| 一边摸一边抽搐一进一出视频| 国产精品偷窥熟女精品视频| 人人澡人人妻人人爽人人蜜桃麻豆| 有人有在线观看的片资源| 狠色狠色狠狠色综合久久| 亚洲AV成人精品午夜一区二区| BBWBBW欧美肥妇PICS| 免费看成熟丰满少妇AⅤ无码精品| 亚洲成人av无码| 亚洲AV噜噜在线成人网站| 亚洲中文AⅤ中文字幕在线| 国外亚洲成AV人片在线观看| 婷婷久久综合九色综合97最多收| 成人国产一区二区三区| 人妻丰满熟妇无码AV| JAPANESEⅩⅩⅩHD中文| 强奷漂亮饱满雪白少妇AV| YY6090新视觉影院| 日韩一区精品视频一区二区| 国产A级作爱片无码| 他的舌头含有起了我的小豆豆| 高清欧美性猛交XXXX黑人猛交| 熟妇人妻中文AV无码| 国产精品无码专区在线播放| 午夜亚洲乱码伦小说区69堂| 国产色无码精品视频免费| 亚洲AV乱码中文一区二区三区| 国内偷自第一区二区三区| 一本大道大臿蕉无码视频| 欧美XXXX黑人又粗又长精品| FREEXXXPORN中国女人| 色欲人妻AAAAAA无码| 国产精品国产自线拍免费| 亚洲AV成人无码精品区 | 少妇人妻AV毛片在线看| 国产精品XXX大片免费观看| 亚洲AV综合A∨一区二区| 久久久久久久久久久综合日本 | 国产激情久久久久影院蜜桃AV| 亚洲VA久久久噜噜噜熟女8| 免费无遮挡无码永久视频 | 波多野结衣美乳人妻HD电影欧美| 日本不卡一区二区三区| 国产精品日本一区二区在线播放| 亚洲AV中文无码乱人伦在线观看| 久久综合九色综合久99| 人妻无码第一区二区三区| JAVAPARSER少妇高潮| 无人区码一码二码三码是 | 亚洲AV成人永久无在线观看| 领导边摸边吃奶边做爽在线观看 | 西西人体自慰扒开下部93| 国产日韩一区二区三区在线观看| 天天躁日日躁狠狠躁欧美老妇小说| 交换配乱吟粗大SNS840| 成人黄网站高清免费视频| 日产精品1卡二卡三卡| 国产成人无码一区二区在线播放| 亚洲欧美性爱视频| 男女高潮免费观看无遮挡| 国产精品一国产精品一K频道| 中文字幕欧美人妻精品一区| 无码成人H动漫在线网站| 免费看人妻丰满熟妇AV无码片| 国产精品99久久久久久人| 400部精品国偷自产在线| 亚洲AV中文无码字幕色本草| 人妻少妇HEYZO无码专区| 久久成人无码专区| 日产精品一线二线三线优势| 国产精品自产Av一区二区三区| ZOOM与人性ZOOM| 97香蕉超级碰碰碰久久兔费| 亚洲精品无码AV专区最新 | 男女一起差差差差差| 黑料不打烊吃瓜爆料| 公交车上噗嗤一声尽根而没| 有人有在线看片的吗www视频| 无码视频一区二区三区| 免费XXXXX大片在线观看一区| 国内美女推油按摩在线播放 | 999WWW成人免费视频| 淫荡集团69视频在线观看| 亚洲国产一卡2卡3卡4卡5公司|