《MYSQL數(shù)據(jù)庫MySQL 性能優(yōu)化神器Explain介紹及使用詳情》要點(diǎn):
本文介紹了MYSQL數(shù)據(jù)庫MySQL 性能優(yōu)化神器Explain介紹及使用詳情,希望對您有用。如果有疑問,可以聯(lián)系我們。
- EXPLAIN?SELECT?*?from?user_info?WHERE?id?<?300;?
MYSQL實(shí)例為了接下來方便演示 EXPLAIN 的使用, 首先我們需要建立兩個(gè)測試用的表, 并添加相應(yīng)的數(shù)據(jù):
?
- CREATE?TABLE?`user_info`?(?
- ??`id`???BIGINT(20)??NOT?NULL?AUTO_INCREMENT,?
- ??`name`?VARCHAR(50)?NOT?NULL?DEFAULT?'',?
- ??`age`??INT(11)??????????????DEFAULT?NULL,?
- ??PRIMARY?KEY?(`id`),?
- ??KEY?`name_index`?(`name`)?
- )?
- ??ENGINE?=?InnoDB?
- ??DEFAULT?CHARSET?=?utf8?
- ?
- INSERT?INTO?user_info?(name,?age)?VALUES?('xys',?20);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('a',?21);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('b',?23);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('c',?50);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('d',?15);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('e',?20);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('f',?21);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('g',?23);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('h',?50);?
- INSERT?INTO?user_info?(name,?age)?VALUES?('i',?15);?
- CREATE?TABLE?`order_info`?(?
- ??`id`???????????BIGINT(20)??NOT?NULL?AUTO_INCREMENT,?
- ??`user_id`??????BIGINT(20)???????????DEFAULT?NULL,?
- ??`product_name`?VARCHAR(50)?NOT?NULL?DEFAULT?'',?
- ??`productor`????VARCHAR(30)??????????DEFAULT?NULL,?
- ??PRIMARY?KEY?(`id`),?
- ??KEY?`user_product_detail_index`?(`user_id`,?`product_name`,?`productor`)?
- )?
- ??ENGINE?=?InnoDB?
- ??DEFAULT?CHARSET?=?utf8?
- ?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(1,?'p1',?'WHH');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(1,?'p2',?'WL');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(1,?'p1',?'DX');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(2,?'p1',?'WHH');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(2,?'p5',?'WL');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(3,?'p3',?'MA');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(4,?'p1',?'WHH');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(6,?'p1',?'WHH');?
- INSERT?INTO?order_info?(user_id,?product_name,?productor)?VALUES?(9,?'p8',?'TE');?
MYSQL實(shí)例
EXPLAIN 命令的輸出內(nèi)容大致如下:
?
- mysql>?explain?select?*?from?user_info?where?id?=?2\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?const?
- possible_keys:?PRIMARY?
- ??????????key:?PRIMARY?
- ??????key_len:?8?
- ??????????ref:?const?
- ?????????rows:?1?
- ?????filtered:?100.00?
- ????????Extra:?NULL?
- 1?row?in?set,?1?warning?(0.00?sec)?
MYSQL實(shí)例
各列的含義如下:
MYSQL實(shí)例接下來我們來重點(diǎn)看一下比較重要的幾個(gè)字段.
select_type
select_type 表示了查詢的類型, 它的常用取值有:
MYSQL實(shí)例最常見的查詢類別應(yīng)該是 SIMPLE 了, 比如當(dāng)我們的查詢沒有子查詢, 也沒有 UNION 查詢時(shí), 那么通常就是 SIMPLE 類型, 例如:
- mysql>?explain?select?*?from?user_info?where?id?=?2\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?const?
- possible_keys:?PRIMARY?
- ??????????key:?PRIMARY?
- ??????key_len:?8?
- ??????????ref:?const?
- ?????????rows:?1?
- ?????filtered:?100.00?
- ????????Extra:?NULL?
- 1?row?in?set,?1?warning?(0.00?sec)?
MYSQL實(shí)例如果我們使用了 UNION 查詢, 那么 EXPLAIN 輸出 的結(jié)果類似如下:
- mysql>?EXPLAIN?(SELECT?*?FROM?user_info??WHERE?id?IN?(1,?2,?3))?
- ????->?UNION?
- ????->?(SELECT?*?FROM?user_info?WHERE?id?IN?(3,?4,?5));?
- +----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+?
- |?id?|?select_type??|?table??????|?partitions?|?type??|?possible_keys?|?key?????|?key_len?|?ref??|?rows?|?filtered?|?Extra???????????|?
- +----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+?
- |??1?|?PRIMARY??????|?user_info??|?NULL???????|?range?|?PRIMARY???????|?PRIMARY?|?8???????|?NULL?|????3?|???100.00?|?Using?where?????|?
- |??2?|?UNION????????|?user_info??|?NULL???????|?range?|?PRIMARY???????|?PRIMARY?|?8???????|?NULL?|????3?|???100.00?|?Using?where?????|?
- |?NULL?|?UNION?RESULT?|?<union1,2>?|?NULL???????|?ALL???|?NULL??????????|?NULL????|?NULL????|?NULL?|?NULL?|?????NULL?|?Using?temporary?|?
- +----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+?
- 3?rows?in?set,?1?warning?(0.00?sec)?
MYSQL實(shí)例table
表示查詢涉及的表或衍生表
type
type 字段比較重要, 它提供了判斷查詢是否高效的重要依據(jù)依據(jù). 通過 type 字段, 我們判斷此次查詢是 全表掃描 還是 索引掃描 等.
type 常用類型
type 常用的取值有:
MYSQL實(shí)例例如下面的這個(gè)查詢, 它使用了主鍵索引, 因此 type 就是 const 類型的.
?
- mysql>?explain?select?*?from?user_info?where?id?=?2\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?const?
- possible_keys:?PRIMARY?
- ??????????key:?PRIMARY?
- ??????key_len:?8?
- ??????????ref:?const?
- ?????????rows:?1?
- ?????filtered:?100.00?
- ????????Extra:?NULL?
- 1?row?in?set,?1?warning?(0.00?sec)?
MYSQL實(shí)例?
- mysql>?EXPLAIN?SELECT?*?FROM?user_info,?order_info?WHERE?user_info.id?=?order_info.user_id\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?order_info?
- ???partitions:?NULL?
- ?????????type:?index?
- possible_keys:?user_product_detail_index?
- ??????????key:?user_product_detail_index?
- ??????key_len:?314?
- ??????????ref:?NULL?
- ?????????rows:?9?
- ?????filtered:?100.00?
- ????????Extra:?Using?where;?Using?index?
- ***************************?2.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?eq_ref?
- possible_keys:?PRIMARY?
- ??????????key:?PRIMARY?
- ??????key_len:?8?
- ??????????ref:?test.order_info.user_id?
- ?????????rows:?1?
- ?????filtered:?100.00?
- ????????Extra:?NULL?
- 2?rows?in?set,?1?warning?(0.00?sec)?
MYSQL實(shí)例例如下面這個(gè)例子中, 就使用到了 ref 類型的查詢:
?
- mysql>?EXPLAIN?SELECT?*?FROM?user_info,?order_info?WHERE?user_info.id?=?order_info.user_id?AND?order_info.user_id?=?5\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?const?
- possible_keys:?PRIMARY?
- ??????????key:?PRIMARY?
- ??????key_len:?8?
- ??????????ref:?const?
- ?????????rows:?1?
- ?????filtered:?100.00?
- ????????Extra:?NULL?
- ***************************?2.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?order_info?
- ???partitions:?NULL?
- ?????????type:?ref?
- possible_keys:?user_product_detail_index?
- ??????????key:?user_product_detail_index?
- ??????key_len:?9?
- ??????????ref:?const?
- ?????????rows:?1?
- ?????filtered:?100.00?
- ????????Extra:?Using?index?
- 2?rows?in?set,?1?warning?(0.01?sec)?
MYSQL實(shí)例?
MYSQL實(shí)例
例如下面的例子就是一個(gè)范圍查詢:
?
- mysql>?EXPLAIN?SELECT?*?
- ????->?????????FROM?user_info?
- ????->?????????WHERE?id?BETWEEN?2?AND?8?\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?range?
- possible_keys:?PRIMARY?
- ??????????key:?PRIMARY?
- ??????key_len:?8?
- ??????????ref:?NULL?
- ?????????rows:?7?
- ?????filtered:?100.00?
- ????????Extra:?Using?where?
- 1?row?in?set,?1?warning?(0.00?sec)?
- mysql>?EXPLAIN?SELECT?name?FROM??user_info?\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?index?
- possible_keys:?NULL?
- ??????????key:?name_index?
- ??????key_len:?152?
- ??????????ref:?NULL?
- ?????????rows:?10?
- ?????filtered:?100.00?
- ????????Extra:?Using?index?
- 1?row?in?set,?1?warning?(0.00?sec)?
- mysql>?EXPLAIN?SELECT?age?FROM??user_info?WHERE?age?=?20?\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?user_info?
- ???partitions:?NULL?
- ?????????type:?ALL?
- possible_keys:?NULL?
- ??????????key:?NULL?
- ??????key_len:?NULL?
- ??????????ref:?NULL?
- ?????????rows:?10?
- ?????filtered:?10.00?
- ????????Extra:?Using?where?
- 1?row?in?set,?1?warning?(0.00?sec)?
上面的例子是從表 order_info 中查詢指定的內(nèi)容, 而我們從此表的建表語句中可以知道, 表 order_info 有一個(gè)聯(lián)合索引:
- mysql>?EXPLAIN?SELECT?*?FROM?order_info?WHERE?user_id?<?3?AND?product_name?=?'p1'?AND?productor?=?'WHH'?\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?order_info?
- ???partitions:?NULL?
- ?????????type:?range?
- possible_keys:?user_product_detail_index?
- ??????????key:?user_product_detail_index?
- ??????key_len:?9?
- ??????????ref:?NULL?
- ?????????rows:?5?
- ?????filtered:?11.11?
- ????????Extra:?Using?where;?Using?index?
- 1?row?in?set,?1?warning?(0.00?sec)?
不過此查詢語句 WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH' 中, 因?yàn)橄冗M(jìn)行 user_id 的范圍查詢, 而根據(jù) 最左前綴匹配 原則, 當(dāng)遇到范圍查詢時(shí), 就停止索引的匹配, 因此實(shí)際上我們使用到的索引的字段只有 user_id, 因此在 EXPLAIN 中, 顯示的 key_len 為 9. 因?yàn)?user_id 字段是 BIGINT, 占用 8 字節(jié), 而 NULL 屬性占用一個(gè)字節(jié), 因此總共是 9 個(gè)字節(jié). 若我們將user_id 字段改為 BIGINT(20) NOT NULL DEFAULT '0', 則 key_length 應(yīng)該是8.
- KEY?`user_product_detail_index`?(`user_id`,?`product_name`,?`productor`)?
- 不過此查詢語句?WHERE?user_id?<?3?AND?product_name?=?'p1'?AND?productor?=?'WHH'?中,?因?yàn)橄冗M(jìn)行?user_id?的范圍查詢,?而根據(jù)?最左前綴匹配?原則,?當(dāng)遇到范圍查詢時(shí),?就停止索引的匹配,?因此實(shí)際上我們使用到的索引的字段只有?user_id,?因此在?EXPLAIN?中,?顯示的?key_len?為?9.?因?yàn)?user_id?字段是?BIGINT,?占用?8?字節(jié),?而?NULL?屬性占用一個(gè)字節(jié),?因此總共是?9?個(gè)字節(jié).?若我們將user_id?字段改為?BIGINT(20)?NOT?NULL?DEFAULT?'0',?則?key_length?應(yīng)該是8.?
- ?
- 上面因?yàn)?最左前綴匹配?原則,?我們的查詢僅僅使用到了聯(lián)合索引的?user_id?字段,?因此效率不算高.?
- ?
- 接下來我們來看一下下一個(gè)例子:?
我們的索引是
- mysql>?EXPLAIN?SELECT?*?FROM?order_info?ORDER?BY?product_name?\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?order_info?
- ???partitions:?NULL?
- ?????????type:?index?
- possible_keys:?NULL?
- ??????????key:?user_product_detail_index?
- ??????key_len:?253?
- ??????????ref:?NULL?
- ?????????rows:?9?
- ?????filtered:?100.00?
- ????????Extra:?Using?index;?Using?filesort?
- 1?row?in?set,?1?warning?(0.00?sec)?
- mysql>?EXPLAIN?SELECT?*?FROM?order_info?ORDER?BY?user_id,?product_name?\G?
- ***************************?1.?row?***************************?
- ???????????id:?1?
- ??select_type:?SIMPLE?
- ????????table:?order_info?
- ???partitions:?NULL?
- ?????????type:?index?
- possible_keys:?NULL?
- ??????????key:?user_product_detail_index?
- ??????key_len:?253?
- ??????????ref:?NULL?
- ?????????rows:?9?
- ?????filtered:?100.00?
- ????????Extra:?Using?index?
- 1?row?in?set,?1?warning?(0.00?sec)?
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/5783.html