mysql explain用法和結果的含義

轉自:http://blog.chinaunix.net/uid-540802-id-3419311.html

explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優化的查詢語句。

使用方法,在select語句前加上explain就可以了:

如:

explain select surname,first_name form a,b where a.id=b.id
EXPLAIN列的解釋:

table:顯示這一行的數據是關於哪張表的

type:這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型爲const、eq_reg、ref、range、index和ALL

   type顯示的是訪問類型,是較爲重要的一個指標,結果值從好到壞依次是
   system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
    一般來說,得保證查詢至少達到range級別,最好能達到ref。

possible_keys:顯示可能應用在這張表中的索引。如果爲空,沒有可能的索引。可以爲相關的域從WHERE語句中選擇一個合適的語句

key: 實際使用的索引。如果爲NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引

key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好

ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數

rows:MYSQL認爲必須檢查的用來返回請求數據的行數

Extra:關於MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這裏可以看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結果是檢索會很慢

extra列返回的描述的意義

Distinct:一旦MYSQL找到了與行相聯合匹配的行,就不再搜索了

Not exists: MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就不再搜索了

Range checked for each Record(index map:#):沒有找到理想的索引,因此對於從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,並用它來從表中返回行。這是使用索引的最慢的連接之一

Using filesort: 看到這個的時候,查詢就需要優化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。它根據連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行

Using index: 列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發生在對錶的全部的請求列都是同一個索引的部分的時候

Using temporary 看到這個的時候,查詢需要優化了。這裏,MYSQL需要創建一個臨時表來存儲結果,這通常發生在對不同的列集進行ORDER BY上,而不是GROUP BY上

Where used 使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,並且連接類型ALL或index,這就會發生,或者是查詢有問題不同連接類型的解釋(按照效率高低的順序排序)

system 表只有一行:system表。這是const連接類型的特殊情況

const:表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因爲只有一行,這個值實際就是常數,因爲MYSQL先讀這個值然後把它當做常數來對待

eq_ref:在連接中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引爲主鍵或惟一鍵的全部時使用

ref:這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時發生。對於之前的表的每一個行聯合,全部記錄都將從表中讀出。這個類型嚴重依賴於根據索引匹配的記錄多少—越少越好

range:這個連接類型使用索引返回一個範圍中的行,比如使用>或<查找東西時發生的情況

index: 這個連接類型對前面的表中的每一個記錄聯合進行完全掃描(比ALL更好,因爲索引一般小於表數據)

ALL:這個連接類型對於前面的每一個記錄聯合進行完全掃描,這一般比較糟糕,應該儘量避免

先看一個例子:

mysql> explain select * from t_order;
±—±------------±--------±-----±--------------±-----±--------±-----±-------±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±------+
| 1 | SIMPLE | t_order | ALL | NULL | NULL | NULL | NULL | 100453 | |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±------+
1 row in set (0.03 sec)
加上extended後之後:

mysql> explain extended select * from t_order;
±—±------------±--------±-----±--------------±-----±--------±-----±-------±---------±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±---------±------+
| 1 | SIMPLE | t_order | ALL | NULL | NULL | NULL | NULL | 100453 | 100.00 | |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±---------±------+
1 row in set, 1 warning (0.00 sec)
有必要解釋一下這個長長的表格裏每一列的含義:

id SELECT識別符。這是SELECT的查詢序列號
select_type
SELECT類型,可以爲以下任何一種:

SIMPLE:簡單SELECT(不使用UNION或子查詢)
PRIMARY:最外面的SELECT
UNION:UNION中的第二個或後面的SELECT語句
DEPENDENT UNION:UNION中的第二個或後面的SELECT語句,取決於外面的查詢
UNION RESULT:UNION 的結果
SUBQUERY:子查詢中的第一個SELECT
DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的查詢
DERIVED:導出表的SELECT(FROM子句的子查詢)
table
輸出的行所引用的表

type
聯接類型。下面給出各種聯接類型,按照從最佳類型到最壞類型進行排序:

system:表僅有一行(=系統表)。這是const聯接類型的一個特例。
const:表最多有一個匹配行,它將在查詢開始時被讀取。因爲僅有一行,在這行的列值可被優化器剩餘部分認爲是常數。const表很快,因爲它們只讀取一次!
eq_ref:對於每個來自於前面的表的行組合,從該表中讀取一行。這可能是最好的聯接類型,除了const類型。
ref:對於每個來自於前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。
ref_or_null:該聯接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。
index_merge:該聯接類型表示使用了索引合併優化方法。
unique_subquery:該類型替換了下面形式的IN子查詢的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一個索引查找函數,可以完全替換子查詢,效率更高。
index_subquery:該聯接類型類似於unique_subquery。可以替換IN子查詢,但只適合下列形式的子查詢中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range:只檢索給定範圍的行,使用一個索引來選擇行。
index:該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因爲索引文件通常比數據文件小。
ALL:對於每個來自於先前的表的行組合,進行完整的表掃描。
possible_keys
指出MySQL能使用哪個索引在該表中找到行

key 顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL。
key_len 顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度爲NULL。
ref 顯示使用哪個列或常數與key一起從表中選擇行。
rows 顯示MySQL認爲它執行查詢時必須檢查的行數。多行之間的數據相乘可以估算要處理的行數。
filtered 顯示了通過條件過濾出的行數的百分比估計值。
Extra
該列包含MySQL解決查詢的詳細信息

Distinct:MySQL發現第1個匹配行後,停止爲當前的行組合搜索更多的行。
Not exists:MySQL能夠對查詢進行LEFT JOIN優化,發現1個匹配LEFT JOIN標準的行後,不再爲前面的的行組合在該表內檢查更多的行。
range checked for each record (index map: #):MySQL沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。
Using index:從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息。
Using temporary:爲了解決查詢,MySQL需要創建一個臨時表來容納結果。
Using where:WHERE 子句用於限制哪一個行匹配下一個表或發送到客戶。
Using sort_union(…), Using union(…), Using intersect(…):這些函數說明如何爲index_merge聯接類型合併索引掃描。
Using index for group-by:類似於訪問表的Using index方式,Using index for group-by表示MySQL發現了一個索引,可以用來查 詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤訪問實際的表。

一.select_type的說明

1.UNION:

當通過union來連接多個查詢結果時,第二個之後的select其select_type爲UNION。

mysql> explain select * from t_order where order_id=100 union select * from t_order where order_id=200;
±—±-------------±-----------±------±--------------±--------±--------±------±-----±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±-------------±-----------±------±--------------±--------±--------±------±-----±------+
| 1 | PRIMARY | t_order | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 2 | UNION | t_order | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | |
±—±-------------±-----------±------±--------------±--------±--------±------±-----±------+
3 rows in set (0.34 sec)
2.DEPENDENT UNION與DEPENDENT SUBQUERY:

當union作爲子查詢時,其中第二個union的select_type就是DEPENDENT UNION。
第一個子查詢的select_type則是DEPENDENT SUBQUERY。

mysql> explain select * from t_order where order_id in (select order_id from t_order where order_id=100 union select order_id from t_order where order_id=200);
±—±-------------------±-----------±------±--------------±--------±--------±------±-------±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±-------------------±-----------±------±--------------±--------±--------±------±-------±------------+
| 1 | PRIMARY | t_order | ALL | NULL | NULL | NULL | NULL | 100453 | Using where |
| 2 | DEPENDENT SUBQUERY | t_order | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
| 3 | DEPENDENT UNION | t_order | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
±—±-------------------±-----------±------±--------------±--------±--------±------±-------±------------+
4 rows in set (0.03 sec)
3.SUBQUERY:

子查詢中的第一個select其select_type爲SUBQUERY。

mysql> explain select * from t_order where order_id=(select order_id from t_order where order_id=100);
±—±------------±--------±------±--------------±--------±--------±------±-----±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------±--------------±--------±--------±------±-----±------------+
| 1 | PRIMARY | t_order | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 2 | SUBQUERY | t_order | const | PRIMARY | PRIMARY | 4 | | 1 | Using index |
±—±------------±--------±------±--------------±--------±--------±------±-----±------------+
2 rows in set (0.03 sec)
4.DERIVED:

當子查詢是from子句時,其select_type爲DERIVED。

mysql> explain select * from (select order_id from t_order where order_id=100) a;
±—±------------±-----------±-------±--------------±--------±--------±-----±-----±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±-----------±-------±--------------±--------±--------±-----±-----±------------+
| 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | t_order | const | PRIMARY | PRIMARY | 4 | | 1 | Using index |
±—±------------±-----------±-------±--------------±--------±--------±-----±-----±------------+
2 rows in set (0.03 sec)
二.type的說明

1.system,const

見上面4.DERIVED的例子。其中第一行的type就是爲system,第二行是const,這兩種聯接類型是最快的。

2.eq_ref

在t_order表中的order_id是主鍵,t_order_ext表中的order_id也是主鍵,該表可以認爲是訂單表的補充信息表,他們的關係是1對1,在下面的例子中可以看到b表的連接類型是eq_ref,這是極快的聯接類型。

mysql> explain select * from t_order a,t_order_ext b where a.order_id=b.order_id;
±—±------------±------±-------±--------------±--------±--------±----------------±-----±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±-------±--------------±--------±--------±----------------±-----±------------+
| 1 | SIMPLE | b | ALL | order_id | NULL | NULL | NULL | 1 | |
| 1 | SIMPLE | a | eq_ref | PRIMARY | PRIMARY | 4 | test.b.order_id | 1 | Using where |
±—±------------±------±-------±--------------±--------±--------±----------------±-----±------------+
2 rows in set (0.00 sec)
3.ref

下面的例子在上面的例子上略作了修改,加上了條件。此時b表的聯接類型變成了ref。因爲所有與a表中order_id=100的匹配記錄都將會從b表獲取。這是比較常見的聯接類型。

mysql> explain select * from t_order a,t_order_ext b where a.order_id=b.order_id and a.order_id=100;
±—±------------±------±------±--------------±---------±--------±------±-----±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±------±--------------±---------±--------±------±-----±------+
| 1 | SIMPLE | a | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 1 | SIMPLE | b | ref | order_id | order_id | 4 | const | 1 | |
±—±------------±------±------±--------------±---------±--------±------±-----±------+
2 rows in set (0.00 sec)
4.ref_or_null

user_id字段是一個可以爲空的字段,並對該字段創建了一個索引。在下面的查詢中可以看到聯接類型爲ref_or_null,這是mysql爲含有null的字段專門做的處理。在我們的表設計中應當儘量避免索引字段爲NULL,因爲這會額外的耗費mysql的處理時間來做優化。

mysql> explain select * from t_order where user_id=100 or user_id is null;
±—±------------±--------±------------±--------------±--------±--------±------±------±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------------±--------------±--------±--------±------±------±------------+
| 1 | SIMPLE | t_order | ref_or_null | user_id | user_id | 5 | const | 50325 | Using where |
±—±------------±--------±------------±--------------±--------±--------±------±------±------------+
1 row in set (0.00 sec)
5.index_merge

經常出現在使用一張表中的多個索引時。mysql會將多個索引合併在一起,如下例:

mysql> explain select * from t_order where order_id=100 or user_id=10;
±—±------------±--------±------------±----------------±----------------±--------±-----±-----±------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------------±----------------±----------------±--------±-----±-----±------------------------------------------+
| 1 | SIMPLE | t_order | index_merge | PRIMARY,user_id | PRIMARY,user_id | 4,5 | NULL | 2 | Using union(PRIMARY,user_id); Using where |
±—±------------±--------±------------±----------------±----------------±--------±-----±-----±------------------------------------------+
1 row in set (0.09 sec)
6.unique_subquery

該聯接類型用於替換value IN (SELECT primary_key FROM single_table WHERE some_expr)這樣的子查詢的ref。注意ref列,其中第二行顯示的是func,表明unique_subquery是一個函數,而不是一個普通的ref。

mysql> explain select * from t_order where order_id in (select order_id from t_order where user_id=10);
±—±-------------------±--------±----------------±----------------±--------±--------±-----±-------±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±-------------------±--------±----------------±----------------±--------±--------±-----±-------±------------+
| 1 | PRIMARY | t_order | ALL | NULL | NULL | NULL | NULL | 100649 | Using where |
| 2 | DEPENDENT SUBQUERY | t_order | unique_subquery | PRIMARY,user_id | PRIMARY | 4 | func | 1 | Using where |
±—±-------------------±--------±----------------±----------------±--------±--------±-----±-------±------------+
2 rows in set (0.00 sec)
7.index_subquery

該聯接類型與上面的太像了,唯一的差別就是子查詢查的不是主鍵而是非唯一索引。

mysql> explain select * from t_order where user_id in (select user_id from t_order where order_id>10);
±—±-------------------±--------±---------------±----------------±--------±--------±-----±-------±-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±-------------------±--------±---------------±----------------±--------±--------±-----±-------±-------------------------+
| 1 | PRIMARY | t_order | ALL | NULL | NULL | NULL | NULL | 100649 | Using where |
| 2 | DEPENDENT SUBQUERY | t_order | index_subquery | PRIMARY,user_id | user_id | 5 | func | 50324 | Using index; Using where |
±—±-------------------±--------±---------------±----------------±--------±--------±-----±-------±-------------------------+
2 rows in set (0.00 sec)
8.range

按指定的範圍進行檢索,很常見。

mysql> explain select * from t_order where user_id in (100,200,300);
±—±------------±--------±------±--------------±--------±--------±-----±-----±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------±--------------±--------±--------±-----±-----±------------+
| 1 | SIMPLE | t_order | range | user_id | user_id | 5 | NULL | 3 | Using where |
±—±------------±--------±------±--------------±--------±--------±-----±-----±------------+
1 row in set (0.00 sec)
9.index

在進行統計時非常常見,此聯接類型實際上會掃描索引樹,僅比ALL快些。

mysql> explain select count(*) from t_order;
±—±------------±--------±------±--------------±--------±--------±-----±-------±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------±--------------±--------±--------±-----±-------±------------+
| 1 | SIMPLE | t_order | index | NULL | user_id | 5 | NULL | 100649 | Using index |
±—±------------±--------±------±--------------±--------±--------±-----±-------±------------+
1 row in set (0.00 sec)
10.ALL

完整的掃描全表,最慢的聯接類型,儘可能的避免。

mysql> explain select * from t_order;
±—±------------±--------±-----±--------------±-----±--------±-----±-------±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±------+
| 1 | SIMPLE | t_order | ALL | NULL | NULL | NULL | NULL | 100649 | |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±------+
1 row in set (0.00 sec)
三.extra的說明

1.Distinct

MySQL發現第1個匹配行後,停止爲當前的行組合搜索更多的行。對於此項沒有找到合適的例子,求指點。

2.Not exists

因爲b表中的order_id是主鍵,不可能爲NULL,所以mysql在用a表的order_id掃描t_order表,並查找b表的行時,如果在b表發現一個匹配的行就不再繼續掃描b了,因爲b表中的order_id字段不可能爲NULL。這樣避免了對b表的多次掃描。

mysql> explain select count(1) from t_order a left join t_order_ext b on a.order_id=b.order_id where b.order_id is null;
±—±------------±------±------±--------------±-------------±--------±----------------±-------±-------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±------±--------------±-------------±--------±----------------±-------±-------------------------------------+
| 1 | SIMPLE | a | index | NULL | express_type | 1 | NULL | 100395 | Using index |
| 1 | SIMPLE | b | ref | order_id | order_id | 4 | test.a.order_id | 1 | Using where; Using index; Not exists |
±—±------------±------±------±--------------±-------------±--------±----------------±-------±-------------------------------------+
2 rows in set (0.01 sec)
3.Range checked for each record

這種情況是mysql沒有發現好的索引可用,速度比沒有索引要快得多。

mysql> explain select * from t_order t, t_order_ext s where s.order_id>=t.order_id and s.order_id<=t.order_id and t.express_type>5;
±—±------------±------±------±---------------------±-------------±--------±-----±-----±-----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±------±---------------------±-------------±--------±-----±-----±-----------------------------------------------+
| 1 | SIMPLE | t | range | PRIMARY,express_type | express_type | 1 | NULL | 1 | Using where |
| 1 | SIMPLE | s | ALL | order_id | NULL | NULL | NULL | 1 | Range checked for each record (index map: 0x1) |
±—±------------±------±------±---------------------±-------------±--------±-----±-----±-----------------------------------------------+
2 rows in set (0.00 sec)
4.Using filesort

在有排序子句的情況下很常見的一種情況。此時mysql會根據聯接類型瀏覽所有符合條件的記錄,並保存排序關鍵字和行指針,然後排序關鍵字並按順序檢索行。

mysql> explain select * from t_order order by express_type;
±—±------------±--------±-----±--------------±-----±--------±-----±-------±---------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±---------------+
| 1 | SIMPLE | t_order | ALL | NULL | NULL | NULL | NULL | 100395 | Using filesort |
±—±------------±--------±-----±--------------±-----±--------±-----±-------±---------------+
1 row in set (0.00 sec)
5.Using index

這是性能很高的一種情況。當查詢所需的數據可以直接從索引樹中檢索到時,就會出現。上面的例子中有很多這樣的例子,不再多舉例了。

6.Using temporary

發生這種情況一般都是需要進行優化的。mysql需要創建一張臨時表用來處理此類查詢。

mysql> explain select * from t_order a left join t_order_ext b on a.order_id=b.order_id group by b.order_id;
±—±------------±------±-----±--------------±---------±--------±----------------±-------±--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±-----±--------------±---------±--------±----------------±-------±--------------------------------+
| 1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 100395 | Using temporary; Using filesort |
| 1 | SIMPLE | b | ref | order_id | order_id | 4 | test.a.order_id | 1 | |
±—±------------±------±-----±--------------±---------±--------±----------------±-------±--------------------------------+
2 rows in set (0.00 sec)
7.Using where

當有where子句時,extra都會有說明。

8.Using sort_union(…)/Using union(…)/Using intersect(…)

下面的例子中user_id是一個檢索範圍,此時mysql會使用sort_union函數來進行索引的合併。而當user_id是一個固定值時,請參看上面type說明5.index_merge的例子,此時會使用union函數進行索引合併。

mysql> explain select * from t_order where order_id=100 or user_id>10;
±—±------------±--------±------------±----------------±----------------±--------±-----±-----±-----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------------±----------------±----------------±--------±-----±-----±-----------------------------------------------+
| 1 | SIMPLE | t_order | index_merge | PRIMARY,user_id | user_id,PRIMARY | 5,4 | NULL | 2 | Using sort_union(user_id,PRIMARY); Using where |
±—±------------±--------±------------±----------------±----------------±--------±-----±-----±-----------------------------------------------+
1 row in set (0.00 sec)
對於Using intersect的例子可以參看下例,user_id與express_type發生了索引交叉合併。

mysql> explain select * from t_order where express_type=1 and user_id=100;
±—±------------±--------±------------±---------------------±---------------------±--------±-----±-----±---------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------------±---------------------±---------------------±--------±-----±-----±---------------------------------------------------+
| 1 | SIMPLE | t_order | index_merge | user_id,express_type | user_id,express_type | 5,1 | NULL | 1 | Using intersect(user_id,express_type); Using where |
±—±------------±--------±------------±---------------------±---------------------±--------±-----±-----±---------------------------------------------------+
1 row in set (0.00 sec)
9.Using index for group-by

表明可以在索引中找到分組所需的所有數據,不需要查詢實際的表。

mysql> explain select user_id from t_order group by user_id;
±—±------------±--------±------±--------------±--------±--------±-----±-----±-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±--------±------±--------------±--------±--------±-----±-----±-------------------------+
| 1 | SIMPLE | t_order | range | NULL | user_id | 5 | NULL | 3 | Using index for group-by |
±—±------------±--------±------±--------------±--------±--------±-----±-----±-------------------------+
1 row in set (0.00 sec)
除了上面的三個說明,還需要注意rows的數值,多行之間的數值是乘積的關係,可以估算大概要處理的行數,如果乘積很大,那就很有優化的必要了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章