日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
你會看MySQL的執(zhí)行計劃(EXPLAIN)嗎?

SQL 執(zhí)行太慢怎么辦?我們通常會使用 EXPLAIN 命令來查看 SQL 的執(zhí)行計劃,然后根據(jù)執(zhí)行計劃找出問題所在并進行優(yōu)化。

專注于為中小企業(yè)提供網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)洛江免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

用法簡介

EXPLAIN 的用法很簡單,只需要在你的 SQL 前面加上 EXPLAIN 即可。例如:

 explain select * from t;

PS:insert、update、delete 同樣可以通過 explain 查看執(zhí)行計劃,不過通常我們更關(guān)心 select 的執(zhí)行情況

你會看到如下輸出:

 +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

執(zhí)行計劃結(jié)果字段說明如下表:

EXPLAIN 的用法非常簡單,看一眼就會。但是要根據(jù)輸出結(jié)果找到問題并解決,就沒那么容易了。就好比操作拍 CT 的機器可能相對簡單,但要從 CT 成像中看出問題并給出治療方案就需要豐富的知識和大量的臨床經(jīng)驗了。

因此,我們需要知道每個字段代表什么指標;什么樣的取值是我們想要的,什么樣是需要優(yōu)化的;最后還要知道如何優(yōu)化成我們想要的值。

字段詳解

id

標識符。查詢操作的序列號。通常都是正整數(shù),但當有 UNION 操作時,該值可以為 NULL。

id 相同

explain select * from t1 where t1.id in (select t2.id from t2);
 +----+-------------+-------+------------+--------+---------------+--------+
| id | select_type | table | partitions | type | possible_keys | ... |
+----+-------------+-------+------------+--------+---------------+--------+
| 1 | SIMPLE | t1 | NULL | ALL | PRIMARY | .... |
| 1 | SIMPLE | t2 | NULL | eq_ref | PRIMARY | .... |
+----+-------------+-------+------------+--------+---------------+--------+
2 rows in set, 1 warning (0.00 sec)

2 rows in set, 1 warning (0.00 sec)

id 不同

 explain select * from t1 where t1.id = (select t2.id from t2);
 +----+-------------+-------+------------+-------+---------------+--------+
| id | select_type | table | partitions | type | possible_keys | ... |
+----+-------------+-------+------------+-------+---------------+--------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | .... |
| 2 | SUBQUERY | t2 | NULL | index | NULL | .... |
+----+-------------+-------+------------+-------+---------------+--------+
2 rows in set, 1 warning (0.00 sec)
id 包含 NULL
 explain select id from t1 union (select id from t2);
+----+--------------+------------+------------+-------+---------------+-----------+
| id | select_type | table | partitions | type | possible_keys | ... |
+------+--------------+------------+------------+-------+---------------+---------+
| 1 | PRIMARY | t1 | NULL | index | NULL | ... |
| 2 | UNION | t2 | NULL | index | NULL | ... |
| NULL | UNION RESULT | | NULL | ALL | NULL | ... |
+------+--------------+------------+------------+-------+---------------+---------+
3 rows in set, 1 warning (0.00 sec)

id 為 NULL 時,table 列值為 < unionM,n > 格式,表示該行為 id 為 m 和 n 聯(lián)合的結(jié)果

id 順序的規(guī)則:如果 id 相同,執(zhí)行順序由上到下;如果不同,執(zhí)行順序由大到小。

select_type

SELECT 類型,常見的取值如下表:

UNION 或者子查詢 MySQL 會自動產(chǎn)生臨時表。派生表可以簡單理解為具有別名的臨時表。生成臨時表的這個動作稱為物化(水變成蒸汽叫汽化)

臨時表通常在內(nèi)存里,當其 size 超過一定范圍會被存入磁盤

 # 臨時表
select * from t1 join t2 on t1.id = t2.id where t1.id > 1;

# 派生表,臨時表取個別名
select * from (select * from t1) t;

type

連接字段為主鍵或者唯一索引,此類型通常出現(xiàn)于多表的join查詢,表示對于前表的每一個結(jié)果,都對應(yīng)后表的唯一一條結(jié)果。并且查詢的比較是=操作,查詢效率比較高。

還有一種 NULL 的情況,比如 select min(id) from t1,但 MySQL 官方?jīng)]有提及這種情況,所以我們不在此討論

性能從優(yōu)到劣依次為:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

優(yōu)化原則:最好做到 const,至少做到 ref,避免 ALL

ref

查詢中用來和索引比較的類型,如:id = 1,值為 const;如果是聯(lián)合查詢或者子查詢則為關(guān)聯(lián)的字段;如果使用了函數(shù),則為 func。

Extra

Extra 用來存放一些附加信息,通常用來配合 type 的輸出來做 SQL 優(yōu)化。

擴展

desc

desc 與 explain 作用相同,可以互相代替,后面的例子中均使用 desc 來查看執(zhí)行計劃。

format

explain/desc 還支持一些參數(shù),format 顧名思義,是用來格式化輸出結(jié)果的。它包括兩種格式化方式:tree 和 json。

比如:

desc format = tree select * from t1 where t1.id in (select t2.id from t2 where t2.id > 1);

輸出格式如下:

 +----------------------------------------------------------------------------------+
| EXPLAIN |
+----------------------------------------------------------------------------------+
| -> Nested loop inner join (cost=0.70 rows=1)
-> Filter: (t2.id > 1) (cost=0.35 rows=1)
-> Index scan on t2 using a2_uidx (cost=0.35 rows=1)
-> Single-row index lookup on t1 using PRIMARY (id=t2.id) (cost=0.35 rows=1)
|
+----------------------------------------------------------------------------------+
1 row in set (0.00 sec)

執(zhí)行計劃結(jié)果以樹形結(jié)構(gòu)展示,可以清晰的看出語句之間的嵌套關(guān)系,還有基本的執(zhí)行成本(cost)。

使用 json 方式:

desc format = json select * from t1;

輸出結(jié)構(gòu)為一個 JSON 結(jié)構(gòu):

 +---------------------------------------------------+
| EXPLAIN |
+---------------------------------------------------+
| {
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "0.35"
},
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows_examined_per_scan": 1,
"rows_produced_per_join": 1,
"filtered": "100.00",
"cost_info": {
"read_cost": "0.25",
"eval_cost": "0.10",
"prefix_cost": "0.35",
"data_read_per_join": "56"
},
"used_columns": [
"id",
"a1",
"b1"
]
}
}
} |
+---------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

簡介表中的 JSON Name 指的就是這里 JSON 結(jié)果的 key

json 格式會展示出更加詳細的信息,可以看到執(zhí)行成本劃分的更加細致了,方便定位到慢 SQL 的問題具體出現(xiàn)在哪個環(huán)節(jié)。

analyze

除了 format 以外,explain/desc 還可以使用 analyze 參數(shù):

 desc analyze select * from t1 where t1.id in (select t2.id from t2 where t2.id > 1);

輸出結(jié)果:

 +-------------------------------------------------------------------------------------------------------+
| EXPLAIN |
+-------------------------------------------------------------------------------------------------------+
| -> Nested loop inner join (cost=0.70 rows=1) (actual time=0.018..0.018 rows=0 loops=1)
-> Filter: (t2.id > 1) (cost=0.35 rows=1) (actual time=0.016..0.016 rows=0 loops=1)
-> Index scan on t2 using a2_uidx (cost=0.35 rows=1) (actual time=0.015..0.015 rows=0 loops=1)
-> Single-row index lookup on t1 using PRIMARY (id=t2.id) (cost=0.35 rows=1) (never executed)
|
+-------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

可以看出,analyze 的輸出結(jié)果是基于 format = tree 的

上面執(zhí)行計劃中(format = json/tree)的執(zhí)行成本(cost)都是估值,而 analyze 中的執(zhí)行成本是真實值。actual time 代表對應(yīng) SQL 執(zhí)行的真實時間,單位為毫秒。

最后

執(zhí)行計劃的結(jié)果中,我們最關(guān)心的是 type,它能夠最直接的反映出 SQL 執(zhí)行效率處在什么級別。然后再結(jié)合其他字段(例如 Extra)來做更細致的分析。還可以通過各種參數(shù),來分解每個環(huán)節(jié)的執(zhí)行情況。


分享文章:你會看MySQL的執(zhí)行計劃(EXPLAIN)嗎?
本文路徑:http://www.5511xx.com/article/dpjjhpe.html